mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2025-11-06 20:18:14 +00:00
ARM: fix peephole optimisation of TST
We were trying to look through COPY instructions, but only to the next instruction in a BB and incorrectly anyway. The cases where that would actually be a good idea are rare enough (and not even tested!) that it's not worth trying to get right. rdar://20721342 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@236050 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
@@ -2315,16 +2315,6 @@ static bool isSuitableForMask(MachineInstr *&MI, unsigned SrcReg,
|
|||||||
if (SrcReg == MI->getOperand(CommonUse ? 1 : 0).getReg())
|
if (SrcReg == MI->getOperand(CommonUse ? 1 : 0).getReg())
|
||||||
return true;
|
return true;
|
||||||
break;
|
break;
|
||||||
case ARM::COPY: {
|
|
||||||
// Walk down one instruction which is potentially an 'and'.
|
|
||||||
const MachineInstr &Copy = *MI;
|
|
||||||
MachineBasicBlock::iterator AND(
|
|
||||||
std::next(MachineBasicBlock::iterator(MI)));
|
|
||||||
if (AND == MI->getParent()->end()) return false;
|
|
||||||
MI = AND;
|
|
||||||
return isSuitableForMask(MI, Copy.getOperand(0).getReg(),
|
|
||||||
CmpMask, true);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
|
|||||||
@@ -8,9 +8,9 @@
|
|||||||
|
|
||||||
%struct.Foo = type { i8* }
|
%struct.Foo = type { i8* }
|
||||||
|
|
||||||
; ARM: foo
|
; ARM-LABEL: foo:
|
||||||
; THUMB: foo
|
; THUMB-LABEL: foo:
|
||||||
; T2: foo
|
; T2-LABEL: foo:
|
||||||
define %struct.Foo* @foo(%struct.Foo* %this, i32 %acc) nounwind readonly align 2 {
|
define %struct.Foo* @foo(%struct.Foo* %this, i32 %acc) nounwind readonly align 2 {
|
||||||
entry:
|
entry:
|
||||||
%scevgep = getelementptr %struct.Foo, %struct.Foo* %this, i32 1
|
%scevgep = getelementptr %struct.Foo, %struct.Foo* %this, i32 1
|
||||||
@@ -83,9 +83,9 @@ sw.epilog: ; preds = %tailrecurse.switch
|
|||||||
|
|
||||||
%struct.S = type { i8* (i8*)*, [1 x i8] }
|
%struct.S = type { i8* (i8*)*, [1 x i8] }
|
||||||
|
|
||||||
; ARM: bar
|
; ARM-LABEL: bar:
|
||||||
; THUMB: bar
|
; THUMB-LABEL: bar:
|
||||||
; T2: bar
|
; T2-LABEL: bar:
|
||||||
; V8-LABEL: bar:
|
; V8-LABEL: bar:
|
||||||
define internal zeroext i8 @bar(%struct.S* %x, %struct.S* nocapture %y) nounwind readonly {
|
define internal zeroext i8 @bar(%struct.S* %x, %struct.S* nocapture %y) nounwind readonly {
|
||||||
entry:
|
entry:
|
||||||
@@ -135,4 +135,26 @@ return: ; preds = %bb2, %bb, %entry
|
|||||||
ret i8 1
|
ret i8 1
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
; We were looking through multiple COPY instructions to find an AND we might
|
||||||
|
; fold into a TST, but in doing so we changed the register being tested allowing
|
||||||
|
; folding of unrelated tests (in this case, a TST against r1 was eliminated in
|
||||||
|
; favour of an AND of r0).
|
||||||
|
|
||||||
|
; ARM-LABEL: test_tst_assessment:
|
||||||
|
; THUMB-LABEL: test_tst_assessment:
|
||||||
|
; T2-LABEL: test_tst_assessment:
|
||||||
|
; V8-LABEL: test_tst_assessment:
|
||||||
|
define i32 @test_tst_assessment(i1 %lhs, i1 %rhs) {
|
||||||
|
%lhs32 = zext i1 %lhs to i32
|
||||||
|
%rhs32 = zext i1 %rhs to i32
|
||||||
|
%diff = sub nsw i32 %lhs32, %rhs32
|
||||||
|
; ARM: tst r1, #1
|
||||||
|
; THUMB: movs [[RTMP:r[0-9]+]], #1
|
||||||
|
; THUMB: tst r1, [[RTMP]]
|
||||||
|
; T2: tst.w r1, #1
|
||||||
|
; V8: tst.w r1, #1
|
||||||
|
ret i32 %diff
|
||||||
|
}
|
||||||
|
|
||||||
!1 = !{!"branch_weights", i32 1, i32 1, i32 3, i32 2 }
|
!1 = !{!"branch_weights", i32 1, i32 1, i32 3, i32 2 }
|
||||||
|
|||||||
Reference in New Issue
Block a user