[InstCombine] Fold add of zext and sext of i1
authorNikita Popov <npopov@redhat.com>
Fri, 14 Jul 2023 12:41:33 +0000 (14:41 +0200)
committerNikita Popov <npopov@redhat.com>
Fri, 14 Jul 2023 12:52:13 +0000 (14:52 +0200)
(zext a) + (sext a) is 0 if a is a bool.

The regression is in a fuzzer-generated test.

Proof: https://alive2.llvm.org/ce/z/KotnN6

llvm/lib/Transforms/InstCombine/InstCombineAddSub.cpp
llvm/test/Transforms/InstCombine/add.ll
llvm/test/Transforms/InstCombine/shift.ll

index 4c437c2..cd47a8b 100644 (file)
@@ -1479,6 +1479,11 @@ Instruction *InstCombinerImpl::visitAdd(BinaryOperator &I) {
        match(RHS, m_ZExt(m_NUWSub(m_Value(B), m_Specific(A))))))
     return new ZExtInst(B, LHS->getType());
 
+  // zext(A) + sext(A) --> 0 if A is i1
+  if (match(&I, m_c_BinOp(m_ZExt(m_Value(A)), m_SExt(m_Deferred(A)))) &&
+      A->getType()->isIntOrIntVectorTy(1))
+    return replaceInstUsesWith(I, Constant::getNullValue(I.getType()));
+
   // A+B --> A|B iff A and B have no bits set in common.
   if (haveNoCommonBitsSet(LHS, RHS, DL, &AC, &I, &DT))
     return BinaryOperator::CreateOr(LHS, RHS);
index 27243d5..3ba01fb 100644 (file)
@@ -3021,10 +3021,7 @@ define <2 x i32> @dec_zext_add_nonzero_vec_poison2(<2 x i8> %x) {
 
 define i32 @add_zext_sext_i1(i1 %a) {
 ; CHECK-LABEL: @add_zext_sext_i1(
-; CHECK-NEXT:    [[ZEXT:%.*]] = zext i1 [[A:%.*]] to i32
-; CHECK-NEXT:    [[SEXT:%.*]] = sext i1 [[A]] to i32
-; CHECK-NEXT:    [[ADD:%.*]] = add nsw i32 [[ZEXT]], [[SEXT]]
-; CHECK-NEXT:    ret i32 [[ADD]]
+; CHECK-NEXT:    ret i32 0
 ;
   %zext = zext i1 %a to i32
   %sext = sext i1 %a to i32
@@ -3034,10 +3031,7 @@ define i32 @add_zext_sext_i1(i1 %a) {
 
 define i32 @add_sext_zext_i1(i1 %a) {
 ; CHECK-LABEL: @add_sext_zext_i1(
-; CHECK-NEXT:    [[ZEXT:%.*]] = zext i1 [[A:%.*]] to i32
-; CHECK-NEXT:    [[SEXT:%.*]] = sext i1 [[A]] to i32
-; CHECK-NEXT:    [[ADD:%.*]] = add nsw i32 [[SEXT]], [[ZEXT]]
-; CHECK-NEXT:    ret i32 [[ADD]]
+; CHECK-NEXT:    ret i32 0
 ;
   %zext = zext i1 %a to i32
   %sext = sext i1 %a to i32
@@ -3047,10 +3041,7 @@ define i32 @add_sext_zext_i1(i1 %a) {
 
 define <2 x i32> @add_zext_sext_i1_vec(<2 x i1> %a) {
 ; CHECK-LABEL: @add_zext_sext_i1_vec(
-; CHECK-NEXT:    [[ZEXT:%.*]] = zext <2 x i1> [[A:%.*]] to <2 x i32>
-; CHECK-NEXT:    [[SEXT:%.*]] = sext <2 x i1> [[A]] to <2 x i32>
-; CHECK-NEXT:    [[ADD:%.*]] = add nsw <2 x i32> [[ZEXT]], [[SEXT]]
-; CHECK-NEXT:    ret <2 x i32> [[ADD]]
+; CHECK-NEXT:    ret <2 x i32> zeroinitializer
 ;
   %zext = zext <2 x i1> %a to <2 x i32>
   %sext = sext <2 x i1> %a to <2 x i32>
index ede8c8c..3db759c 100644 (file)
@@ -1689,6 +1689,10 @@ define i177 @lshr_out_of_range(i177 %Y, ptr %A2, ptr %ptr) {
 ; https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=26716
 define i177 @lshr_out_of_range2(i177 %Y, ptr %A2, ptr %ptr) {
 ; CHECK-LABEL: @lshr_out_of_range2(
+; CHECK-NEXT:    [[C8:%.*]] = icmp ne i177 [[Y:%.*]], 0
+; CHECK-NEXT:    [[TMP1:%.*]] = sext i1 [[C8]] to i64
+; CHECK-NEXT:    [[G18:%.*]] = getelementptr ptr, ptr [[A2:%.*]], i64 [[TMP1]]
+; CHECK-NEXT:    store ptr [[G18]], ptr [[PTR:%.*]], align 8
 ; CHECK-NEXT:    ret i177 0
 ;
   %B5 = udiv i177 %Y, -1