From 9f7d13868a875696a52f6c5d1f51a489e15eef26 Mon Sep 17 00:00:00 2001 From: Tim Northover Date: Tue, 28 Apr 2015 22:03:55 +0000 Subject: [PATCH] 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 --- lib/Target/ARM/ARMBaseInstrInfo.cpp | 10 ------- test/CodeGen/ARM/arm-and-tst-peephole.ll | 34 +++++++++++++++++++----- 2 files changed, 28 insertions(+), 16 deletions(-) diff --git a/lib/Target/ARM/ARMBaseInstrInfo.cpp b/lib/Target/ARM/ARMBaseInstrInfo.cpp index a370ab37675..e722ffb94cf 100644 --- a/lib/Target/ARM/ARMBaseInstrInfo.cpp +++ b/lib/Target/ARM/ARMBaseInstrInfo.cpp @@ -2315,16 +2315,6 @@ static bool isSuitableForMask(MachineInstr *&MI, unsigned SrcReg, if (SrcReg == MI->getOperand(CommonUse ? 1 : 0).getReg()) return true; 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; diff --git a/test/CodeGen/ARM/arm-and-tst-peephole.ll b/test/CodeGen/ARM/arm-and-tst-peephole.ll index 3096587ccb0..04eae8f9afe 100644 --- a/test/CodeGen/ARM/arm-and-tst-peephole.ll +++ b/test/CodeGen/ARM/arm-and-tst-peephole.ll @@ -8,9 +8,9 @@ %struct.Foo = type { i8* } -; ARM: foo -; THUMB: foo -; T2: foo +; ARM-LABEL: foo: +; THUMB-LABEL: foo: +; T2-LABEL: foo: define %struct.Foo* @foo(%struct.Foo* %this, i32 %acc) nounwind readonly align 2 { entry: %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] } -; ARM: bar -; THUMB: bar -; T2: bar +; ARM-LABEL: bar: +; THUMB-LABEL: bar: +; T2-LABEL: bar: ; V8-LABEL: bar: define internal zeroext i8 @bar(%struct.S* %x, %struct.S* nocapture %y) nounwind readonly { entry: @@ -135,4 +135,26 @@ return: ; preds = %bb2, %bb, %entry 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 }