From db059db6ad199a4188d6a5ce3e7812e291afeb6e Mon Sep 17 00:00:00 2001 From: Tim Northover Date: Tue, 28 Jul 2015 22:42:32 +0000 Subject: [PATCH] AArch64: be careful of large immediates when optimising cmps. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@243492 91177308-0d34-0410-b5e6-96231b3b80d8 --- .../AArch64/AArch64ConditionOptimizer.cpp | 17 ++++++++---- .../AArch64/combine-comparisons-by-cse.ll | 26 +++++++++++++++++++ 2 files changed, 38 insertions(+), 5 deletions(-) diff --git a/lib/Target/AArch64/AArch64ConditionOptimizer.cpp b/lib/Target/AArch64/AArch64ConditionOptimizer.cpp index b9e41c61def..99a5eaa7aef 100644 --- a/lib/Target/AArch64/AArch64ConditionOptimizer.cpp +++ b/lib/Target/AArch64/AArch64ConditionOptimizer.cpp @@ -154,11 +154,18 @@ MachineInstr *AArch64ConditionOptimizer::findSuitableCompare( // cmn is an alias for adds with a dead destination register. case AArch64::ADDSWri: case AArch64::ADDSXri: - if (MRI->use_empty(I->getOperand(0).getReg())) - return I; - - DEBUG(dbgs() << "Destination of cmp is not dead, " << *I << '\n'); - return nullptr; + if (!I->getOperand(2).isImm()) { + DEBUG(dbgs() << "Immediate of cmp is symbolic, " << *I << '\n'); + return nullptr; + } else if (I->getOperand(2).getImm() << I->getOperand(3).getImm() >= + 0xfff) { + DEBUG(dbgs() << "Immediate of cmp may be out of range, " << *I << '\n'); + return nullptr; + } else if (!MRI->use_empty(I->getOperand(0).getReg())) { + DEBUG(dbgs() << "Destination of cmp is not dead, " << *I << '\n'); + return nullptr; + } + return I; // Prevent false positive case like: // cmp w19, #0 diff --git a/test/CodeGen/AArch64/combine-comparisons-by-cse.ll b/test/CodeGen/AArch64/combine-comparisons-by-cse.ll index c78fabac618..004267f4e4e 100644 --- a/test/CodeGen/AArch64/combine-comparisons-by-cse.ll +++ b/test/CodeGen/AArch64/combine-comparisons-by-cse.ll @@ -403,6 +403,32 @@ return: ; preds = %land.lhs.true, %con ret i32 %retval.0 } +define void @cmp_shifted(i32 %in, i32 %lhs, i32 %rhs) { +; CHECK-LABEL: cmp_shifted: +; CHECK: cmp w0, #1 +; [...] +; CHECK: cmp w0, #2, lsl #12 + + %tst_low = icmp sgt i32 %in, 0 + br i1 %tst_low, label %true, label %false + +true: + call i32 @zoo(i32 128) + ret void + +false: + %tst = icmp sgt i32 %in, 8191 + br i1 %tst, label %truer, label %falser + +truer: + call i32 @zoo(i32 42) + ret void + +falser: + call i32 @zoo(i32 1) + ret void +} + declare i32 @zoo(i32) declare double @yoo(i32)