ARM: Teach A15 SDOptimizer to properly handle D-reg by-lane.
authorJim Grosbach <grosbach@apple.com>
Wed, 4 Sep 2013 19:08:44 +0000 (19:08 +0000)
committerJim Grosbach <grosbach@apple.com>
Wed, 4 Sep 2013 19:08:44 +0000 (19:08 +0000)
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

lib/Target/ARM/A15SDOptimizer.cpp

index e8c2f7ccf6d4f36dfe95a2581a537c83223da84b..ff585b41a2aa65be545b0dc50613264498c18489 100644 (file)
@@ -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");