diff options
author | Jakob Stoklund Olesen <stoklund@2pi.dk> | 2012-09-10 19:17:25 +0000 |
---|---|---|
committer | Jakob Stoklund Olesen <stoklund@2pi.dk> | 2012-09-10 19:17:25 +0000 |
commit | 519daf5d2dd80614ac4e529b199e6f3e595bfc80 (patch) | |
tree | a32634c3414828cc97a351d4112ba6acca490888 | |
parent | 2c38a6615a693d0a43159825da2358126473502b (diff) | |
download | external_llvm-519daf5d2dd80614ac4e529b199e6f3e595bfc80.zip external_llvm-519daf5d2dd80614ac4e529b199e6f3e595bfc80.tar.gz external_llvm-519daf5d2dd80614ac4e529b199e6f3e595bfc80.tar.bz2 |
Don't attempt to use flags from predicated instructions.
The ARM backend can eliminate cmp instructions by reusing flags from a
nearby sub instruction with similar arguments.
Don't do that if the sub is predicated - the flags are not written
unconditionally.
<rdar://problem/12263428>
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@163535 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r-- | lib/Target/ARM/ARMBaseInstrInfo.cpp | 10 | ||||
-rw-r--r-- | test/CodeGen/ARM/sub-cmp-peephole.ll | 21 |
2 files changed, 29 insertions, 2 deletions
diff --git a/lib/Target/ARM/ARMBaseInstrInfo.cpp b/lib/Target/ARM/ARMBaseInstrInfo.cpp index 10c41ee..e2f0d7d 100644 --- a/lib/Target/ARM/ARMBaseInstrInfo.cpp +++ b/lib/Target/ARM/ARMBaseInstrInfo.cpp @@ -2028,13 +2028,14 @@ optimizeCompareInstr(MachineInstr *CmpInstr, unsigned SrcReg, unsigned SrcReg2, // Masked compares sometimes use the same register as the corresponding 'and'. if (CmpMask != ~0) { - if (!isSuitableForMask(MI, SrcReg, CmpMask, false)) { + if (!isSuitableForMask(MI, SrcReg, CmpMask, false) || isPredicated(MI)) { MI = 0; for (MachineRegisterInfo::use_iterator UI = MRI->use_begin(SrcReg), UE = MRI->use_end(); UI != UE; ++UI) { if (UI->getParent() != CmpInstr->getParent()) continue; MachineInstr *PotentialAND = &*UI; - if (!isSuitableForMask(PotentialAND, SrcReg, CmpMask, true)) + if (!isSuitableForMask(PotentialAND, SrcReg, CmpMask, true) || + isPredicated(PotentialAND)) continue; MI = PotentialAND; break; @@ -2100,6 +2101,10 @@ optimizeCompareInstr(MachineInstr *CmpInstr, unsigned SrcReg, unsigned SrcReg2, // The single candidate is called MI. if (!MI) MI = Sub; + // We can't use a predicated instruction - it doesn't always write the flags. + if (isPredicated(MI)) + return false; + switch (MI->getOpcode()) { default: break; case ARM::RSBrr: @@ -2206,6 +2211,7 @@ optimizeCompareInstr(MachineInstr *CmpInstr, unsigned SrcReg, unsigned SrcReg2, // Toggle the optional operand to CPSR. MI->getOperand(5).setReg(ARM::CPSR); MI->getOperand(5).setIsDef(true); + assert(!isPredicated(MI) && "Can't use flags from predicated instruction"); CmpInstr->eraseFromParent(); // Modify the condition code of operands in OperandsToUpdate. diff --git a/test/CodeGen/ARM/sub-cmp-peephole.ll b/test/CodeGen/ARM/sub-cmp-peephole.ll index 6fcbdee..2961b94 100644 --- a/test/CodeGen/ARM/sub-cmp-peephole.ll +++ b/test/CodeGen/ARM/sub-cmp-peephole.ll @@ -63,3 +63,24 @@ if.then: if.else: ret i32 %sub } + +; If the sub/rsb instruction is predicated, we can't use the flags. +; <rdar://problem/12263428> +; Test case from MultiSource/Benchmarks/Ptrdist/bc/number.s +; CHECK: bc_raise +; CHECK: rsbeq +; CHECK: cmp +define i32 @bc_raise() nounwind ssp { +entry: + %val.2.i = select i1 undef, i32 0, i32 undef + %sub.i = sub nsw i32 0, %val.2.i + %retval.0.i = select i1 undef, i32 %val.2.i, i32 %sub.i + %cmp1 = icmp eq i32 %retval.0.i, 0 + br i1 %cmp1, label %land.lhs.true, label %if.end11 + +land.lhs.true: ; preds = %num2long.exit + ret i32 17 + +if.end11: ; preds = %num2long.exit + ret i32 23 +} |