diff options
author | Jim Grosbach <grosbach@apple.com> | 2013-09-04 19:08:44 +0000 |
---|---|---|
committer | Jim Grosbach <grosbach@apple.com> | 2013-09-04 19:08:44 +0000 |
commit | 1bfa80359edc004bc8a91999de7c8e16708d2206 (patch) | |
tree | b238c6fa310540f864b26b929e3a4fd6ed5a0a88 /lib/Target/ARM/A15SDOptimizer.cpp | |
parent | 1d7df349ab7fa051ffe88589b06a1aa514f84a00 (diff) | |
download | llvm-1bfa80359edc004bc8a91999de7c8e16708d2206.tar.gz llvm-1bfa80359edc004bc8a91999de7c8e16708d2206.tar.bz2 llvm-1bfa80359edc004bc8a91999de7c8e16708d2206.tar.xz |
ARM: Teach A15 SDOptimizer to properly handle D-reg by-lane.
These instructions, such as vmul.f32, require the second source operand to
be in D0-D15 rather than the full D0-D31. When optimizing, make sure to
account for that by constraining the register class of a replacement virtual
register to be compatible with the virtual register(s) it's replacing.
I've been unsuccessful in creating a non-fragile regression test. This issue
was detected by the LLVM nightly test suite running on an A15 (Bullet).
PR17093: http://llvm.org/bugs/show_bug.cgi?id=17093
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@189972 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/Target/ARM/A15SDOptimizer.cpp')
-rw-r--r-- | lib/Target/ARM/A15SDOptimizer.cpp | 7 |
1 files changed, 7 insertions, 0 deletions
diff --git a/lib/Target/ARM/A15SDOptimizer.cpp b/lib/Target/ARM/A15SDOptimizer.cpp index e8c2f7ccf6..ff585b41a2 100644 --- a/lib/Target/ARM/A15SDOptimizer.cpp +++ b/lib/Target/ARM/A15SDOptimizer.cpp @@ -657,6 +657,13 @@ bool A15SDOptimizer::runOnInstruction(MachineInstr *MI) { Modified = true; for (SmallVectorImpl<MachineOperand *>::const_iterator I = Uses.begin(), E = Uses.end(); I != E; ++I) { + // Make sure to constrain the register class of the new register to + // match what we're replacing. Otherwise we can optimize a DPR_VFP2 + // reference into a plain DPR, and that will end poorly. NewReg is + // always virtual here, so there will always be a matching subclass + // to find. + MRI->constrainRegClass(NewReg, MRI->getRegClass((*I)->getReg())); + DEBUG(dbgs() << "Replacing operand " << **I << " with " << PrintReg(NewReg) << "\n"); |