diff options
author | Evan Cheng <evan.cheng@apple.com> | 2009-09-22 08:34:46 +0000 |
---|---|---|
committer | Evan Cheng <evan.cheng@apple.com> | 2009-09-22 08:34:46 +0000 |
commit | 08d1e41c107af1e08988bc54eef8d2a83cc6e322 (patch) | |
tree | 7f5383c0a7264af6a039b45f1906ffc51a5f94e0 | |
parent | 28830b39b4bd2fec7ba937b49d1389ac0b56c322 (diff) | |
download | bcm5719-llvm-08d1e41c107af1e08988bc54eef8d2a83cc6e322.tar.gz bcm5719-llvm-08d1e41c107af1e08988bc54eef8d2a83cc6e322.zip |
Fix PR5024. LiveVariables::FindLastPartialDef should return a set of sub-registers that were defined by the last partial def, not just a single sub-register.
llvm-svn: 82535
-rw-r--r-- | llvm/lib/CodeGen/LiveVariables.cpp | 28 | ||||
-rw-r--r-- | llvm/test/CodeGen/ARM/2009-09-21-LiveVariablesBug.ll | 14 |
2 files changed, 36 insertions, 6 deletions
diff --git a/llvm/lib/CodeGen/LiveVariables.cpp b/llvm/lib/CodeGen/LiveVariables.cpp index 2da1be9ab6e..e8a94bdca40 100644 --- a/llvm/lib/CodeGen/LiveVariables.cpp +++ b/llvm/lib/CodeGen/LiveVariables.cpp @@ -180,9 +180,9 @@ void LiveVariables::HandleVirtRegDef(unsigned Reg, MachineInstr *MI) { } /// FindLastPartialDef - Return the last partial def of the specified register. -/// Also returns the sub-register that's defined. +/// Also returns the sub-registers that're defined by the instruction. MachineInstr *LiveVariables::FindLastPartialDef(unsigned Reg, - unsigned &PartDefReg) { + SmallSet<unsigned,4> &PartDefRegs) { unsigned LastDefReg = 0; unsigned LastDefDist = 0; MachineInstr *LastDef = NULL; @@ -198,7 +198,23 @@ MachineInstr *LiveVariables::FindLastPartialDef(unsigned Reg, LastDefDist = Dist; } } - PartDefReg = LastDefReg; + + if (!LastDef) + return 0; + + PartDefRegs.insert(LastDefReg); + for (unsigned i = 0, e = LastDef->getNumOperands(); i != e; ++i) { + MachineOperand &MO = LastDef->getOperand(i); + if (!MO.isReg() || !MO.isDef() || MO.getReg() == 0) + continue; + unsigned DefReg = MO.getReg(); + if (TRI->isSubRegister(Reg, DefReg)) { + PartDefRegs.insert(DefReg); + for (const unsigned *SubRegs = TRI->getSubRegisters(DefReg); + unsigned SubReg = *SubRegs; ++SubRegs) + PartDefRegs.insert(SubReg); + } + } return LastDef; } @@ -216,8 +232,8 @@ void LiveVariables::HandlePhysRegUse(unsigned Reg, MachineInstr *MI) { // ... // = EAX // All of the sub-registers must have been defined before the use of Reg! - unsigned PartDefReg = 0; - MachineInstr *LastPartialDef = FindLastPartialDef(Reg, PartDefReg); + SmallSet<unsigned, 4> PartDefRegs; + MachineInstr *LastPartialDef = FindLastPartialDef(Reg, PartDefRegs); // If LastPartialDef is NULL, it must be using a livein register. if (LastPartialDef) { LastPartialDef->addOperand(MachineOperand::CreateReg(Reg, true/*IsDef*/, @@ -228,7 +244,7 @@ void LiveVariables::HandlePhysRegUse(unsigned Reg, MachineInstr *MI) { unsigned SubReg = *SubRegs; ++SubRegs) { if (Processed.count(SubReg)) continue; - if (SubReg == PartDefReg || TRI->isSubRegister(PartDefReg, SubReg)) + if (PartDefRegs.count(SubReg)) continue; // This part of Reg was defined before the last partial def. It's killed // here. diff --git a/llvm/test/CodeGen/ARM/2009-09-21-LiveVariablesBug.ll b/llvm/test/CodeGen/ARM/2009-09-21-LiveVariablesBug.ll new file mode 100644 index 00000000000..aace4751915 --- /dev/null +++ b/llvm/test/CodeGen/ARM/2009-09-21-LiveVariablesBug.ll @@ -0,0 +1,14 @@ +; RUN: llc < %s -mtriple=armv7-none-linux-gnueabi -mattr=+neon + +; PR5024 + +%bar = type { <4 x float> } +%foo = type { %bar, %bar, %bar, %bar } + +declare arm_aapcs_vfpcc <4 x float> @bbb(%bar*) nounwind + +define arm_aapcs_vfpcc void @aaa(%foo* noalias sret %agg.result, %foo* %tfrm) nounwind { +entry: + %0 = call arm_aapcs_vfpcc <4 x float> @bbb(%bar* undef) nounwind ; <<4 x float>> [#uses=0] + ret void +} |