diff options
-rw-r--r-- | lib/CodeGen/TwoAddressInstructionPass.cpp | 12 | ||||
-rw-r--r-- | test/CodeGen/Thumb/2009-07-20-TwoAddrBug.ll | 11 |
2 files changed, 19 insertions, 4 deletions
diff --git a/lib/CodeGen/TwoAddressInstructionPass.cpp b/lib/CodeGen/TwoAddressInstructionPass.cpp index 83468d9..ebdf9cf 100644 --- a/lib/CodeGen/TwoAddressInstructionPass.cpp +++ b/lib/CodeGen/TwoAddressInstructionPass.cpp @@ -879,10 +879,14 @@ bool TwoAddressInstructionPass::runOnMachineFunction(MachineFunction &MF) { // so, swap the B and C operands. This makes the live ranges of A // and C joinable. // FIXME: This code also works for A := B op C instructions. - if (TID.isCommutable() && mi->getNumOperands() >= 3) { - assert(mi->getOperand(3-si).isReg() && - "Not a proper commutative instruction!"); - unsigned regC = mi->getOperand(3-si).getReg(); + unsigned SrcOp1, SrcOp2; + if (TID.isCommutable() && mi->getNumOperands() >= 3 && + TII->findCommutedOpIndices(mi, SrcOp1, SrcOp2)) { + unsigned regC = 0; + if (si == SrcOp1) + regC = mi->getOperand(SrcOp2).getReg(); + else if (si == SrcOp2) + regC = mi->getOperand(SrcOp1).getReg(); if (isKilled(*mi, regC, MRI, TII)) { if (CommuteInstruction(mi, mbbi, regB, regC, Dist)) { ++NumCommuted; diff --git a/test/CodeGen/Thumb/2009-07-20-TwoAddrBug.ll b/test/CodeGen/Thumb/2009-07-20-TwoAddrBug.ll new file mode 100644 index 0000000..3e18d29 --- /dev/null +++ b/test/CodeGen/Thumb/2009-07-20-TwoAddrBug.ll @@ -0,0 +1,11 @@ +; RUN: llvm-as < %s | llc -mtriple=thumbv6-apple-darwin10 + +@Time.2535 = external global i64 ; <i64*> [#uses=2] + +define arm_apcscc i64 @millisecs() nounwind { +entry: + %0 = load i64* @Time.2535, align 4 ; <i64> [#uses=2] + %1 = add i64 %0, 1 ; <i64> [#uses=1] + store i64 %1, i64* @Time.2535, align 4 + ret i64 %0 +} |