[llvm] f400daa - [InstCombine] limit zext-of-icmp folds to bit-hacks

Sanjay Patel via llvm-commits llvm-commits at lists.llvm.org
Mon Jan 9 13:30:26 PST 2023


Author: Sanjay Patel
Date: 2023-01-09T16:29:24-05:00
New Revision: f400daae902875b488c92b13322e39f41eb20934

URL: https://github.com/llvm/llvm-project/commit/f400daae902875b488c92b13322e39f41eb20934
DIFF: https://github.com/llvm/llvm-project/commit/f400daae902875b488c92b13322e39f41eb20934.diff

LOG: [InstCombine] limit zext-of-icmp folds to bit-hacks

In the changed tests, we avoid creating extra instructions,
and there are no obvious regressions in IR tests at least.

Codegen should be able to create the shift+mask form if that
is profitable.

This is a more general fix for issue #59897 than 0eedc9e56712 .

Added: 
    

Modified: 
    llvm/lib/Transforms/InstCombine/InstCombineCasts.cpp
    llvm/test/Transforms/InstCombine/zext.ll

Removed: 
    


################################################################################
diff  --git a/llvm/lib/Transforms/InstCombine/InstCombineCasts.cpp b/llvm/lib/Transforms/InstCombine/InstCombineCasts.cpp
index 7b17a8b9757a..d9f89962c100 100644
--- a/llvm/lib/Transforms/InstCombine/InstCombineCasts.cpp
+++ b/llvm/lib/Transforms/InstCombine/InstCombineCasts.cpp
@@ -1024,7 +1024,9 @@ Instruction *InstCombinerImpl::transformZExtICmp(ICmpInst *Cmp,
     // zext (X == 0) to i32 --> (X>>1)^1 iff X has only the 2nd bit set.
     // zext (X != 0) to i32 --> X        iff X has only the low bit set.
     // zext (X != 0) to i32 --> X>>1     iff X has only the 2nd bit set.
-    if (Op1CV->isZero() && Cmp->isEquality()) {
+    if (Op1CV->isZero() && Cmp->isEquality() &&
+        (Cmp->getOperand(0)->getType() == Zext.getType() ||
+         Cmp->getPredicate() == ICmpInst::ICMP_NE)) {
       // If Op1C some other power of two, convert:
       KnownBits Known = computeKnownBits(Cmp->getOperand(0), 0, &Zext);
 

diff  --git a/llvm/test/Transforms/InstCombine/zext.ll b/llvm/test/Transforms/InstCombine/zext.ll
index 938978ab6bd9..c0275e99c53f 100644
--- a/llvm/test/Transforms/InstCombine/zext.ll
+++ b/llvm/test/Transforms/InstCombine/zext.ll
@@ -645,10 +645,9 @@ define i64 @and_trunc_extra_use1_wider_src(i65 %x, i32 %y) {
 
 define i16 @zext_icmp_eq0_pow2(i32 %x) {
 ; CHECK-LABEL: @zext_icmp_eq0_pow2(
-; CHECK-NEXT:    [[TMP1:%.*]] = trunc i32 [[X:%.*]] to i16
-; CHECK-NEXT:    [[TMP2:%.*]] = lshr i16 [[TMP1]], 2
-; CHECK-NEXT:    [[TMP3:%.*]] = and i16 [[TMP2]], 1
-; CHECK-NEXT:    [[Z:%.*]] = xor i16 [[TMP3]], 1
+; CHECK-NEXT:    [[M:%.*]] = and i32 [[X:%.*]], 4
+; CHECK-NEXT:    [[I:%.*]] = icmp eq i32 [[M]], 0
+; CHECK-NEXT:    [[Z:%.*]] = zext i1 [[I]] to i16
 ; CHECK-NEXT:    ret i16 [[Z]]
 ;
   %m = and i32 %x, 4
@@ -661,9 +660,8 @@ define i16 @zext_icmp_eq0_pow2_use1(i32 %x) {
 ; CHECK-LABEL: @zext_icmp_eq0_pow2_use1(
 ; CHECK-NEXT:    [[M:%.*]] = and i32 [[X:%.*]], 4
 ; CHECK-NEXT:    call void @use32(i32 [[M]])
-; CHECK-NEXT:    [[M_LOBIT:%.*]] = lshr exact i32 [[M]], 2
-; CHECK-NEXT:    [[TMP1:%.*]] = trunc i32 [[M_LOBIT]] to i16
-; CHECK-NEXT:    [[Z:%.*]] = xor i16 [[TMP1]], 1
+; CHECK-NEXT:    [[I:%.*]] = icmp eq i32 [[M]], 0
+; CHECK-NEXT:    [[Z:%.*]] = zext i1 [[I]] to i16
 ; CHECK-NEXT:    ret i16 [[Z]]
 ;
   %m = and i32 %x, 4
@@ -678,9 +676,7 @@ define i16 @zext_icmp_eq0_pow2_use2(i32 %x) {
 ; CHECK-NEXT:    [[M:%.*]] = and i32 [[X:%.*]], 4
 ; CHECK-NEXT:    [[I:%.*]] = icmp eq i32 [[M]], 0
 ; CHECK-NEXT:    call void @use1(i1 [[I]])
-; CHECK-NEXT:    [[M_LOBIT:%.*]] = lshr exact i32 [[M]], 2
-; CHECK-NEXT:    [[TMP1:%.*]] = trunc i32 [[M_LOBIT]] to i16
-; CHECK-NEXT:    [[Z:%.*]] = xor i16 [[TMP1]], 1
+; CHECK-NEXT:    [[Z:%.*]] = zext i1 [[I]] to i16
 ; CHECK-NEXT:    ret i16 [[Z]]
 ;
   %m = and i32 %x, 4


        


More information about the llvm-commits mailing list