[llvm] r328119 - [InstCombine] add folds for xor-of-icmp signbit tests (PR36682)

Sanjay Patel via llvm-commits llvm-commits at lists.llvm.org
Wed Mar 21 14:02:59 PDT 2018


Thanks for letting me know.

I think I see the problem - I forgot to make sure the source operand types
of each compare match

I'll confirm if you send the failure that you have.

On Wed, Mar 21, 2018 at 2:41 PM, Reid Kleckner <rnk at google.com> wrote:

> This changes causes assertions when compiling safe_numerics_unittest.cpp
> in Chromium with MSan:
> https://ci.chromium.org/buildbot/chromium.clang/ToTLinuxMSan/1945
>
> I have reverted this change in r328145. I will send you pre-processed
> source offline that reproduces the problem.
>
>
> On Wed, Mar 21, 2018 at 10:20 AM Sanjay Patel via llvm-commits <
> llvm-commits at lists.llvm.org> wrote:
>
>> Author: spatel
>> Date: Wed Mar 21 10:17:13 2018
>> New Revision: 328119
>>
>> URL: http://llvm.org/viewvc/llvm-project?rev=328119&view=rev
>> Log:
>> [InstCombine] add folds for xor-of-icmp signbit tests (PR36682)
>>
>> This is part of solving:
>> https://bugs.llvm.org/show_bug.cgi?id=36682
>>
>> There's also a leftover improvement from the long-ago-closed:
>> https://bugs.llvm.org/show_bug.cgi?id=5438
>>
>> https://rise4fun.com/Alive/dC1
>>
>>
>> Modified:
>>     llvm/trunk/lib/Transforms/InstCombine/InstCombineAndOrXor.cpp
>>     llvm/trunk/test/Transforms/InstCombine/compare-signs.ll
>>     llvm/trunk/test/Transforms/InstCombine/xor-icmps.ll
>>
>> Modified: llvm/trunk/lib/Transforms/InstCombine/InstCombineAndOrXor.cpp
>> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/
>> Transforms/InstCombine/InstCombineAndOrXor.cpp?rev=
>> 328119&r1=328118&r2=328119&view=diff
>> ============================================================
>> ==================
>> --- llvm/trunk/lib/Transforms/InstCombine/InstCombineAndOrXor.cpp
>> (original)
>> +++ llvm/trunk/lib/Transforms/InstCombine/InstCombineAndOrXor.cpp Wed
>> Mar 21 10:17:13 2018
>> @@ -2363,6 +2363,36 @@ Value *InstCombiner::foldXorOfICmps(ICmp
>>      }
>>    }
>>
>> +  // TODO: This can be generalized to compares of non-signbits using
>> +  // decomposeBitTestICmp(). It could be enhanced more by using
>> (something like)
>> +  // foldLogOpOfMaskedICmps().
>> +  ICmpInst::Predicate PredL = LHS->getPredicate();
>> +  ICmpInst::Predicate PredR = RHS->getPredicate();
>> +  Value *LHS0 = LHS->getOperand(0), *LHS1 = LHS->getOperand(1);
>> +  Value *RHS0 = RHS->getOperand(0), *RHS1 = RHS->getOperand(1);
>> +  if ((LHS->hasOneUse() || RHS->hasOneUse()) && PredL == PredR) {
>> +    // (X > -1) ^ (Y > -1) --> (X ^ Y) < 0
>> +    // (X <  0) ^ (Y <  0) --> (X ^ Y) < 0
>> +    if ((match(LHS1, m_AllOnes()) && match(RHS1, m_AllOnes()) &&
>> +         PredL == CmpInst::ICMP_SGT) ||
>> +        (match(LHS1, m_Zero()) && match(RHS1, m_Zero()) &&
>> +         PredL == CmpInst::ICMP_SLT)) {
>> +      Value *Zero = ConstantInt::getNullValue(LHS0->getType());
>> +      return Builder.CreateICmpSLT(Builder.CreateXor(LHS0, RHS0), Zero);
>> +    }
>> +  }
>> +  if ((LHS->hasOneUse() || RHS->hasOneUse())) {
>> +    // (X > -1) ^ (Y <  0) --> (X ^ Y) > -1
>> +    // (X <  0) ^ (Y > -1) --> (X ^ Y) > -1
>> +    if ((match(LHS1, m_AllOnes()) && match(RHS1, m_Zero()) &&
>> +         PredL == CmpInst::ICMP_SGT && PredR == CmpInst::ICMP_SLT) ||
>> +        (match(LHS1, m_Zero()) && match(RHS1, m_AllOnes()) &&
>> +         PredL == CmpInst::ICMP_SLT && PredR == CmpInst::ICMP_SGT)) {
>> +      Value *MinusOne = ConstantInt::getAllOnesValue(LHS0->getType());
>> +      return Builder.CreateICmpSGT(Builder.CreateXor(LHS0, RHS0),
>> MinusOne);
>> +    }
>> +  }
>> +
>>    // Instead of trying to imitate the folds for and/or, decompose this
>> 'xor'
>>    // into those logic ops. That is, try to turn this into an and-of-icmps
>>    // because we have many folds for that pattern.
>>
>> Modified: llvm/trunk/test/Transforms/InstCombine/compare-signs.ll
>> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/
>> Transforms/InstCombine/compare-signs.ll?rev=328119&
>> r1=328118&r2=328119&view=diff
>> ============================================================
>> ==================
>> --- llvm/trunk/test/Transforms/InstCombine/compare-signs.ll (original)
>> +++ llvm/trunk/test/Transforms/InstCombine/compare-signs.ll Wed Mar 21
>> 10:17:13 2018
>> @@ -1,15 +1,14 @@
>>  ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
>>  ; RUN: opt -instcombine -S < %s | FileCheck %s
>> +
>>  ; PR5438
>>
>> -; TODO: This should also optimize down.
>>  define i32 @test1(i32 %a, i32 %b) nounwind readnone {
>>  ; CHECK-LABEL: @test1(
>> -; CHECK-NEXT:    [[T0:%.*]] = icmp sgt i32 [[A:%.*]], -1
>> -; CHECK-NEXT:    [[T1:%.*]] = icmp slt i32 [[B:%.*]], 0
>> -; CHECK-NEXT:    [[T2:%.*]] = xor i1 [[T1]], [[T0]]
>> -; CHECK-NEXT:    [[T3:%.*]] = zext i1 [[T2]] to i32
>> -; CHECK-NEXT:    ret i32 [[T3]]
>> +; CHECK-NEXT:    [[TMP1:%.*]] = xor i32 [[B:%.*]], [[A:%.*]]
>> +; CHECK-NEXT:    [[DOTLOBIT:%.*]] = lshr i32 [[TMP1]], 31
>> +; CHECK-NEXT:    [[DOTLOBIT_NOT:%.*]] = xor i32 [[DOTLOBIT]], 1
>> +; CHECK-NEXT:    ret i32 [[DOTLOBIT_NOT]]
>>  ;
>>    %t0 = icmp sgt i32 %a, -1
>>    %t1 = icmp slt i32 %b, 0
>> @@ -36,7 +35,7 @@ define i32 @test2(i32 %a, i32 %b) nounwi
>>
>>  define i32 @test3(i32 %a, i32 %b) nounwind readnone {
>>  ; CHECK-LABEL: @test3(
>> -; CHECK-NEXT:    [[T2_UNSHIFTED:%.*]] = xor i32 %a, %b
>> +; CHECK-NEXT:    [[T2_UNSHIFTED:%.*]] = xor i32 [[A:%.*]], [[B:%.*]]
>>  ; CHECK-NEXT:    [[T2_UNSHIFTED_LOBIT:%.*]] = lshr i32 [[T2_UNSHIFTED]],
>> 31
>>  ; CHECK-NEXT:    [[T2_UNSHIFTED_LOBIT_NOT:%.*]] = xor i32
>> [[T2_UNSHIFTED_LOBIT]], 1
>>  ; CHECK-NEXT:    ret i32 [[T2_UNSHIFTED_LOBIT_NOT]]
>> @@ -68,7 +67,7 @@ define <2 x i32> @test3vec(<2 x i32> %a,
>>  ; is one, not zero.
>>  define i32 @test3i(i32 %a, i32 %b) nounwind readnone {
>>  ; CHECK-LABEL: @test3i(
>> -; CHECK-NEXT:    [[T01:%.*]] = xor i32 %a, %b
>> +; CHECK-NEXT:    [[T01:%.*]] = xor i32 [[A:%.*]], [[B:%.*]]
>>  ; CHECK-NEXT:    [[TMP1:%.*]] = lshr i32 [[T01]], 31
>>  ; CHECK-NEXT:    [[T4:%.*]] = xor i32 [[TMP1]], 1
>>  ; CHECK-NEXT:    ret i32 [[T4]]
>> @@ -84,7 +83,7 @@ define i32 @test3i(i32 %a, i32 %b) nounw
>>
>>  define i1 @test4a(i32 %a) {
>>  ; CHECK-LABEL: @test4a(
>> -; CHECK-NEXT:    [[C:%.*]] = icmp slt i32 %a, 1
>> +; CHECK-NEXT:    [[C:%.*]] = icmp slt i32 [[A:%.*]], 1
>>  ; CHECK-NEXT:    ret i1 [[C]]
>>  ;
>>    %l = ashr i32 %a, 31
>> @@ -97,7 +96,7 @@ define i1 @test4a(i32 %a) {
>>
>>  define <2 x i1> @test4a_vec(<2 x i32> %a) {
>>  ; CHECK-LABEL: @test4a_vec(
>> -; CHECK-NEXT:    [[C:%.*]] = icmp slt <2 x i32> %a, <i32 1, i32 1>
>> +; CHECK-NEXT:    [[C:%.*]] = icmp slt <2 x i32> [[A:%.*]], <i32 1, i32 1>
>>  ; CHECK-NEXT:    ret <2 x i1> [[C]]
>>  ;
>>    %l = ashr <2 x i32> %a, <i32 31, i32 31>
>> @@ -110,7 +109,7 @@ define <2 x i1> @test4a_vec(<2 x i32> %a
>>
>>  define i1 @test4b(i64 %a) {
>>  ; CHECK-LABEL: @test4b(
>> -; CHECK-NEXT:    [[C:%.*]] = icmp slt i64 %a, 1
>> +; CHECK-NEXT:    [[C:%.*]] = icmp slt i64 [[A:%.*]], 1
>>  ; CHECK-NEXT:    ret i1 [[C]]
>>  ;
>>    %l = ashr i64 %a, 63
>> @@ -123,7 +122,7 @@ define i1 @test4b(i64 %a) {
>>
>>  define i1 @test4c(i64 %a) {
>>  ; CHECK-LABEL: @test4c(
>> -; CHECK-NEXT:    [[C:%.*]] = icmp slt i64 %a, 1
>> +; CHECK-NEXT:    [[C:%.*]] = icmp slt i64 [[A:%.*]], 1
>>  ; CHECK-NEXT:    ret i1 [[C]]
>>  ;
>>    %l = ashr i64 %a, 63
>> @@ -137,7 +136,7 @@ define i1 @test4c(i64 %a) {
>>
>>  define <2 x i1> @test4c_vec(<2 x i64> %a) {
>>  ; CHECK-LABEL: @test4c_vec(
>> -; CHECK-NEXT:    [[C:%.*]] = icmp slt <2 x i64> %a, <i64 1, i64 1>
>> +; CHECK-NEXT:    [[C:%.*]] = icmp slt <2 x i64> [[A:%.*]], <i64 1, i64 1>
>>  ; CHECK-NEXT:    ret <2 x i1> [[C]]
>>  ;
>>    %l = ashr <2 x i64> %a, <i64 63, i64 63>
>>
>> Modified: llvm/trunk/test/Transforms/InstCombine/xor-icmps.ll
>> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/
>> Transforms/InstCombine/xor-icmps.ll?rev=328119&r1=328118&
>> r2=328119&view=diff
>> ============================================================
>> ==================
>> --- llvm/trunk/test/Transforms/InstCombine/xor-icmps.ll (original)
>> +++ llvm/trunk/test/Transforms/InstCombine/xor-icmps.ll Wed Mar 21
>> 10:17:13 2018
>> @@ -42,10 +42,9 @@ define i1 @eq_ne_zero(i4 %x, i4 %y) {
>>
>>  define i1 @slt_zero(i4 %x, i4 %y) {
>>  ; CHECK-LABEL: @slt_zero(
>> -; CHECK-NEXT:    [[I0:%.*]] = icmp slt i4 [[X:%.*]], 0
>> -; CHECK-NEXT:    [[I1:%.*]] = icmp slt i4 [[Y:%.*]], 0
>> -; CHECK-NEXT:    [[R:%.*]] = xor i1 [[I0]], [[I1]]
>> -; CHECK-NEXT:    ret i1 [[R]]
>> +; CHECK-NEXT:    [[TMP1:%.*]] = xor i4 [[X:%.*]], [[Y:%.*]]
>> +; CHECK-NEXT:    [[TMP2:%.*]] = icmp slt i4 [[TMP1]], 0
>> +; CHECK-NEXT:    ret i1 [[TMP2]]
>>  ;
>>    %i0 = icmp slt i4 %x, 0
>>    %i1 = icmp slt i4 %y, 0
>> @@ -68,10 +67,9 @@ define i1 @sgt_zero(i4 %x, i4 %y) {
>>
>>  define i1 @sgt_minus1(i4 %x, i4 %y) {
>>  ; CHECK-LABEL: @sgt_minus1(
>> -; CHECK-NEXT:    [[I0:%.*]] = icmp sgt i4 [[X:%.*]], -1
>> -; CHECK-NEXT:    [[I1:%.*]] = icmp sgt i4 [[Y:%.*]], -1
>> -; CHECK-NEXT:    [[R:%.*]] = xor i1 [[I0]], [[I1]]
>> -; CHECK-NEXT:    ret i1 [[R]]
>> +; CHECK-NEXT:    [[TMP1:%.*]] = xor i4 [[X:%.*]], [[Y:%.*]]
>> +; CHECK-NEXT:    [[TMP2:%.*]] = icmp slt i4 [[TMP1]], 0
>> +; CHECK-NEXT:    ret i1 [[TMP2]]
>>  ;
>>    %i0 = icmp sgt i4 %x, -1
>>    %i1 = icmp sgt i4 %y, -1
>> @@ -81,10 +79,9 @@ define i1 @sgt_minus1(i4 %x, i4 %y) {
>>
>>  define i1 @slt_zero_sgt_minus1(i4 %x, i4 %y) {
>>  ; CHECK-LABEL: @slt_zero_sgt_minus1(
>> -; CHECK-NEXT:    [[I0:%.*]] = icmp slt i4 [[X:%.*]], 0
>> -; CHECK-NEXT:    [[I1:%.*]] = icmp sgt i4 [[Y:%.*]], -1
>> -; CHECK-NEXT:    [[R:%.*]] = xor i1 [[I0]], [[I1]]
>> -; CHECK-NEXT:    ret i1 [[R]]
>> +; CHECK-NEXT:    [[TMP1:%.*]] = xor i4 [[X:%.*]], [[Y:%.*]]
>> +; CHECK-NEXT:    [[TMP2:%.*]] = icmp sgt i4 [[TMP1]], -1
>> +; CHECK-NEXT:    ret i1 [[TMP2]]
>>  ;
>>    %i0 = icmp slt i4 %x, 0
>>    %i1 = icmp sgt i4 %y, -1
>> @@ -94,10 +91,9 @@ define i1 @slt_zero_sgt_minus1(i4 %x, i4
>>
>>  define <2 x i1> @sgt_minus1_slt_zero_sgt(<2 x i4> %x, <2 x i4> %y) {
>>  ; CHECK-LABEL: @sgt_minus1_slt_zero_sgt(
>> -; CHECK-NEXT:    [[I1:%.*]] = icmp sgt <2 x i4> [[X:%.*]], <i4 -1, i4 -1>
>> -; CHECK-NEXT:    [[I0:%.*]] = icmp slt <2 x i4> [[Y:%.*]],
>> zeroinitializer
>> -; CHECK-NEXT:    [[R:%.*]] = xor <2 x i1> [[I0]], [[I1]]
>> -; CHECK-NEXT:    ret <2 x i1> [[R]]
>> +; CHECK-NEXT:    [[TMP1:%.*]] = xor <2 x i4> [[Y:%.*]], [[X:%.*]]
>> +; CHECK-NEXT:    [[TMP2:%.*]] = icmp sgt <2 x i4> [[TMP1]], <i4 -1, i4
>> -1>
>> +; CHECK-NEXT:    ret <2 x i1> [[TMP2]]
>>  ;
>>    %i1 = icmp sgt <2 x i4> %x, <i4 -1, i4 -1>
>>    %i0 = icmp slt <2 x i4> %y, zeroinitializer
>>
>>
>> _______________________________________________
>> llvm-commits mailing list
>> llvm-commits at lists.llvm.org
>> http://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-commits
>>
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20180321/4376b669/attachment.html>


More information about the llvm-commits mailing list