mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2024-12-13 20:32:21 +00:00
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
This commit is contained in:
parent
2c38a6615a
commit
519daf5d2d
@ -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.
|
||||
|
@ -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
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user