[PATCH] D24480: [InstCombine] remove fold: zext(bool) + C -> bool ? C + 1 : C

Sanjay Patel via llvm-commits llvm-commits at lists.llvm.org
Mon Sep 26 15:28:43 PDT 2016


spatel updated this revision to Diff 72579.
spatel added a comment.

Ping.

Patch updated:
Added comment about this case of sext over zext as suggested by Eli.


https://reviews.llvm.org/D24480

Files:
  lib/Transforms/InstCombine/InstCombineAddSub.cpp
  test/Transforms/InstCombine/icmp-div-constant.ll
  test/Transforms/InstCombine/zext-bool-add-sub.ll

Index: test/Transforms/InstCombine/zext-bool-add-sub.ll
===================================================================
--- test/Transforms/InstCombine/zext-bool-add-sub.ll
+++ test/Transforms/InstCombine/zext-bool-add-sub.ll
@@ -5,8 +5,9 @@
 
 define i32 @a(i1 zeroext %x, i1 zeroext %y) {
 ; CHECK-LABEL: @a(
+; CHECK-NEXT:    [[CONV:%.*]] = zext i1 %x to i32
 ; CHECK-NEXT:    [[CONV3_NEG:%.*]] = sext i1 %y to i32
-; CHECK-NEXT:    [[SUB:%.*]] = select i1 %x, i32 2, i32 1
+; CHECK-NEXT:    [[SUB:%.*]] = add nuw nsw i32 [[CONV]], 1
 ; CHECK-NEXT:    [[ADD:%.*]] = add nsw i32 [[SUB]], [[CONV3_NEG]]
 ; CHECK-NEXT:    ret i32 [[ADD]]
 ;
@@ -47,8 +48,8 @@
 define i32 @PR30273_three_bools(i1 %x, i1 %y, i1 %z) {
 ; CHECK-LABEL: @PR30273_three_bools(
 ; CHECK-NEXT:    [[FROMBOOL:%.*]] = zext i1 %x to i32
-; CHECK-NEXT:    [[ADD1:%.*]] = select i1 %x, i32 2, i32 1
-; CHECK-NEXT:    [[SEL1:%.*]] = select i1 %y, i32 [[ADD1]], i32 [[FROMBOOL]]
+; CHECK-NEXT:    [[ADD1:%.*]] = zext i1 %y to i32
+; CHECK-NEXT:    [[SEL1:%.*]] = add nuw nsw i32 [[FROMBOOL]], [[ADD1]]
 ; CHECK-NEXT:    [[ADD2:%.*]] = zext i1 %z to i32
 ; CHECK-NEXT:    [[SEL2:%.*]] = add nuw nsw i32 [[SEL1]], [[ADD2]]
 ; CHECK-NEXT:    ret i32 [[SEL2]]
Index: test/Transforms/InstCombine/icmp-div-constant.ll
===================================================================
--- test/Transforms/InstCombine/icmp-div-constant.ll
+++ test/Transforms/InstCombine/icmp-div-constant.ll
@@ -12,8 +12,8 @@
 ; CHECK-NEXT:    [[TOBOOL:%.*]] = icmp eq i16 %a, 0
 ; CHECK-NEXT:    br i1 [[TOBOOL]], label %then, label %exit
 ; CHECK:       then:
-; CHECK-NEXT:    [[NOT_CMP:%.*]] = icmp eq i16 %c, 0
-; CHECK-NEXT:    [[PHITMP1:%.*]] = sext i1 [[NOT_CMP]] to i32
+; CHECK-NEXT:    [[TMP0:%.*]] = icmp eq i16 %c, 0
+; CHECK-NEXT:    [[PHITMP1:%.*]] = sext i1 [[TMP0]] to i32
 ; CHECK-NEXT:    br label %exit
 ; CHECK:       exit:
 ; CHECK-NEXT:    [[PHI:%.*]] = phi i32 [ -1, %entry ], [ [[PHITMP1]], %then ]
@@ -68,8 +68,8 @@
 ; CHECK-NEXT:    [[TOBOOL:%.*]] = icmp eq i16 %a, 0
 ; CHECK-NEXT:    br i1 [[TOBOOL]], label %then, label %exit
 ; CHECK:       then:
-; CHECK-NEXT:    [[NOT_CMP:%.*]] = icmp eq i16 %c, 0
-; CHECK-NEXT:    [[PHITMP1:%.*]] = sext i1 [[NOT_CMP]] to i32
+; CHECK-NEXT:    [[TMP0:%.*]] = icmp eq i16 %c, 0
+; CHECK-NEXT:    [[PHITMP1:%.*]] = sext i1 [[TMP0]] to i32
 ; CHECK-NEXT:    br label %exit
 ; CHECK:       exit:
 ; CHECK-NEXT:    [[PHI:%.*]] = phi i32 [ -1, %entry ], [ [[PHITMP1]], %then ]
Index: lib/Transforms/InstCombine/InstCombineAddSub.cpp
===================================================================
--- lib/Transforms/InstCombine/InstCombineAddSub.cpp
+++ lib/Transforms/InstCombine/InstCombineAddSub.cpp
@@ -1067,10 +1067,21 @@
     if (SimplifyDemandedInstructionBits(I))
       return &I;
 
-    // zext(bool) + C -> bool ? C + 1 : C
-    if (ZExtInst *ZI = dyn_cast<ZExtInst>(LHS))
-      if (ZI->getSrcTy()->isIntegerTy(1))
-        return SelectInst::Create(ZI->getOperand(0), AddOne(CI), CI);
+    // add (zext (icmp Pred X, Y)), -1 --> sext (icmp Pred' X, Y)
+    // In general, we prefer to have zext rather than sext for better
+    // value-tracking potential, but in this case, we get to eliminate an add.
+    Instruction *ZextOp;
+    ICmpInst::Predicate Pred;
+    Value *X, *Y;
+    if (CI->getSExtValue() == -1 && match(LHS, m_ZExt(m_Instruction(ZextOp))) &&
+        match(ZextOp, m_OneUse(m_ICmp(Pred, m_Value(X), m_Value(Y))))) {
+      // We have this pattern: if the compare is true, return 0;
+      //                       if the compare is false, return -1.
+      // Transform it to: if the inverse compare is true, return -1;
+      //                  if the inverse compare is false, return 0.
+      auto *Cmp = Builder->CreateICmp(CmpInst::getInversePredicate(Pred), X, Y);
+      return CastInst::Create(Instruction::SExt, Cmp, I.getType());
+    }
 
     Value *XorLHS = nullptr; ConstantInt *XorRHS = nullptr;
     if (match(LHS, m_Xor(m_Value(XorLHS), m_ConstantInt(XorRHS)))) {


-------------- next part --------------
A non-text attachment was scrubbed...
Name: D24480.72579.patch
Type: text/x-patch
Size: 4029 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20160926/74e1b28c/attachment.bin>


More information about the llvm-commits mailing list