diff options
| author | Craig Topper <craig.topper@intel.com> | 2017-09-26 18:47:25 +0000 |
|---|---|---|
| committer | Craig Topper <craig.topper@intel.com> | 2017-09-26 18:47:25 +0000 |
| commit | 8bf622174d699e9a09bd7de2dc85b2c8fe38f176 (patch) | |
| tree | b2a71514ca4a431e351bed6e53fa556fcb7ab44e | |
| parent | dffc55c1cd4cec1f165c097333eca792757d786b (diff) | |
| download | bcm5719-llvm-8bf622174d699e9a09bd7de2dc85b2c8fe38f176.tar.gz bcm5719-llvm-8bf622174d699e9a09bd7de2dc85b2c8fe38f176.zip | |
[InstCombine] Remove one use restriction on the shift for calls to foldICmpAndShift.
If this transformation succeeds, we're going to remove our dependency on the shift by rewriting the and. So it doesn't matter how many uses the shift has.
This distributes the one use check to other transforms in foldICmpAndConstConst that do need it.
Differential Revision: https://reviews.llvm.org/D38206
llvm-svn: 314233
| -rw-r--r-- | llvm/lib/Transforms/InstCombine/InstCombineCompares.cpp | 6 | ||||
| -rw-r--r-- | llvm/test/Transforms/InstCombine/icmp.ll | 19 |
2 files changed, 22 insertions, 3 deletions
diff --git a/llvm/lib/Transforms/InstCombine/InstCombineCompares.cpp b/llvm/lib/Transforms/InstCombine/InstCombineCompares.cpp index 0c434a54cbe..ea175cd10ff 100644 --- a/llvm/lib/Transforms/InstCombine/InstCombineCompares.cpp +++ b/llvm/lib/Transforms/InstCombine/InstCombineCompares.cpp @@ -1646,7 +1646,7 @@ Instruction *InstCombiner::foldICmpAndConstConst(ICmpInst &Cmp, if (!match(And->getOperand(1), m_APInt(C2))) return nullptr; - if (!And->hasOneUse() || !And->getOperand(0)->hasOneUse()) + if (!And->hasOneUse()) return nullptr; // If the LHS is an 'and' of a truncate and we can widen the and/compare to @@ -1658,7 +1658,7 @@ Instruction *InstCombiner::foldICmpAndConstConst(ICmpInst &Cmp, // set or if it is an equality comparison. Extending a relational comparison // when we're checking the sign bit would not work. Value *W; - if (match(And->getOperand(0), m_Trunc(m_Value(W))) && + if (match(And->getOperand(0), m_OneUse(m_Trunc(m_Value(W)))) && (Cmp.isEquality() || (!C1->isNegative() && !C2->isNegative()))) { // TODO: Is this a good transform for vectors? Wider types may reduce // throughput. Should this transform be limited (even for scalars) by using @@ -1680,7 +1680,7 @@ Instruction *InstCombiner::foldICmpAndConstConst(ICmpInst &Cmp, // (icmp pred (and A, (or (shl 1, B), 1), 0)) // // iff pred isn't signed - if (!Cmp.isSigned() && C1->isNullValue() && + if (!Cmp.isSigned() && C1->isNullValue() && And->getOperand(0)->hasOneUse() && match(And->getOperand(1), m_One())) { Constant *One = cast<Constant>(And->getOperand(1)); Value *Or = And->getOperand(0); diff --git a/llvm/test/Transforms/InstCombine/icmp.ll b/llvm/test/Transforms/InstCombine/icmp.ll index 68d98de0b4e..18d449228bd 100644 --- a/llvm/test/Transforms/InstCombine/icmp.ll +++ b/llvm/test/Transforms/InstCombine/icmp.ll @@ -1615,6 +1615,25 @@ define <2 x i1> @icmp_add_and_shr_ne_0_vec(<2 x i32> %X) { ret <2 x i1> %tobool } +; Variation of the above with an extra use of the shift +define i1 @icmp_and_shr_multiuse(i32 %X) { +; CHECK-LABEL: @icmp_and_shr_multiuse( +; CHECK-NEXT: [[AND:%.*]] = and i32 [[X:%.*]], 240 +; CHECK-NEXT: [[AND2:%.*]] = and i32 [[X]], 496 +; CHECK-NEXT: [[TOBOOL:%.*]] = icmp ne i32 [[AND]], 224 +; CHECK-NEXT: [[TOBOOL2:%.*]] = icmp ne i32 [[AND2]], 432 +; CHECK-NEXT: [[AND3:%.*]] = and i1 [[TOBOOL]], [[TOBOOL2]] +; CHECK-NEXT: ret i1 [[AND3]] +; + %shr = lshr i32 %X, 4 + %and = and i32 %shr, 15 + %and2 = and i32 %shr, 31 ; second use of the shift + %tobool = icmp ne i32 %and, 14 + %tobool2 = icmp ne i32 %and2, 27 + %and3 = and i1 %tobool, %tobool2 + ret i1 %and3 +} + ; PR16244 define i1 @test71(i8* %x) { ; CHECK-LABEL: @test71( |

