diff --git a/lib/Transforms/InstCombine/InstCombineAddSub.cpp b/lib/Transforms/InstCombine/InstCombineAddSub.cpp index bf92b5dc559..e2d4774b71f 100644 --- a/lib/Transforms/InstCombine/InstCombineAddSub.cpp +++ b/lib/Transforms/InstCombine/InstCombineAddSub.cpp @@ -1118,6 +1118,12 @@ Instruction *InstCombiner::visitAdd(BinaryOperator &I) { return BinaryOperator::CreateSub(RHS, A); } + // Canonicalize sext to zext for better value tracking potential. + // add A, sext(B) --> sub A, zext(B) + if (match(&I, m_c_Add(m_Value(A), m_OneUse(m_SExt(m_Value(B))))) && + B->getType()->isIntOrIntVectorTy(1)) + return BinaryOperator::CreateSub(A, Builder.CreateZExt(B, Ty)); + // A + -B --> A - B if (match(RHS, m_Neg(m_Value(B)))) return BinaryOperator::CreateSub(LHS, B); diff --git a/test/Transforms/InstCombine/add.ll b/test/Transforms/InstCombine/add.ll index 9685b011304..008f5e2eb2d 100644 --- a/test/Transforms/InstCombine/add.ll +++ b/test/Transforms/InstCombine/add.ll @@ -25,8 +25,7 @@ define <2 x i32> @select_0_or_1_from_bool_vec(<2 x i1> %x) { define i32 @select_C_minus_1_or_C_from_bool(i1 %x) { ; CHECK-LABEL: @select_C_minus_1_or_C_from_bool( -; CHECK-NEXT: [[EXT:%.*]] = sext i1 [[X:%.*]] to i32 -; CHECK-NEXT: [[ADD:%.*]] = add nsw i32 [[EXT]], 42 +; CHECK-NEXT: [[ADD:%.*]] = select i1 [[X:%.*]], i32 41, i32 42 ; CHECK-NEXT: ret i32 [[ADD]] ; %ext = sext i1 %x to i32 @@ -36,8 +35,7 @@ define i32 @select_C_minus_1_or_C_from_bool(i1 %x) { define <2 x i32> @select_C_minus_1_or_C_from_bool_vec(<2 x i1> %x) { ; CHECK-LABEL: @select_C_minus_1_or_C_from_bool_vec( -; CHECK-NEXT: [[EXT:%.*]] = sext <2 x i1> [[X:%.*]] to <2 x i32> -; CHECK-NEXT: [[ADD:%.*]] = add nsw <2 x i32> [[EXT]], +; CHECK-NEXT: [[ADD:%.*]] = select <2 x i1> [[X:%.*]], <2 x i32> , <2 x i32> ; CHECK-NEXT: ret <2 x i32> [[ADD]] ; %ext = sext <2 x i1> %x to <2 x i32> diff --git a/test/Transforms/InstCombine/apint-shift.ll b/test/Transforms/InstCombine/apint-shift.ll index 52602dd7f45..495d9d6d8b2 100644 --- a/test/Transforms/InstCombine/apint-shift.ll +++ b/test/Transforms/InstCombine/apint-shift.ll @@ -531,7 +531,11 @@ define i40 @test26(i40 %A) { ; https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=9880 define i177 @ossfuzz_9880(i177 %X) { ; CHECK-LABEL: @ossfuzz_9880( -; CHECK-NEXT: ret i177 1 +; CHECK-NEXT: [[A:%.*]] = alloca i177, align 8 +; CHECK-NEXT: [[L1:%.*]] = load i177, i177* [[A]], align 8 +; CHECK-NEXT: [[TMP1:%.*]] = icmp eq i177 [[L1]], 0 +; CHECK-NEXT: [[B1:%.*]] = zext i1 [[TMP1]] to i177 +; CHECK-NEXT: ret i177 [[B1]] ; %A = alloca i177 %L1 = load i177, i177* %A diff --git a/test/Transforms/InstCombine/logical-select.ll b/test/Transforms/InstCombine/logical-select.ll index 999e4512723..b8decb07114 100644 --- a/test/Transforms/InstCombine/logical-select.ll +++ b/test/Transforms/InstCombine/logical-select.ll @@ -515,10 +515,10 @@ define <4 x i32> @vec_sel_xor(<4 x i32> %a, <4 x i32> %b, <4 x i1> %c) { define <4 x i32> @vec_sel_xor_multi_use(<4 x i32> %a, <4 x i32> %b, <4 x i1> %c) { ; CHECK-LABEL: @vec_sel_xor_multi_use( ; CHECK-NEXT: [[TMP1:%.*]] = xor <4 x i1> [[C:%.*]], -; CHECK-NEXT: [[MASK_FLIP1:%.*]] = sext <4 x i1> [[TMP1]] to <4 x i32> ; CHECK-NEXT: [[TMP2:%.*]] = xor <4 x i1> [[C]], ; CHECK-NEXT: [[TMP3:%.*]] = select <4 x i1> [[TMP2]], <4 x i32> [[A:%.*]], <4 x i32> [[B:%.*]] -; CHECK-NEXT: [[ADD:%.*]] = add <4 x i32> [[TMP3]], [[MASK_FLIP1]] +; CHECK-NEXT: [[TMP4:%.*]] = zext <4 x i1> [[TMP1]] to <4 x i32> +; CHECK-NEXT: [[ADD:%.*]] = sub <4 x i32> [[TMP3]], [[TMP4]] ; CHECK-NEXT: ret <4 x i32> [[ADD]] ; %mask = sext <4 x i1> %c to <4 x i32> diff --git a/test/Transforms/InstCombine/select.ll b/test/Transforms/InstCombine/select.ll index c601a98f062..97203768213 100644 --- a/test/Transforms/InstCombine/select.ll +++ b/test/Transforms/InstCombine/select.ll @@ -694,8 +694,8 @@ define i32 @test41(i1 %cond, i32 %x, i32 %y) { define i32 @test42(i32 %x, i32 %y) { ; CHECK-LABEL: @test42( ; CHECK-NEXT: [[COND:%.*]] = icmp eq i32 [[X:%.*]], 0 -; CHECK-NEXT: [[B:%.*]] = sext i1 [[COND]] to i32 -; CHECK-NEXT: [[C:%.*]] = add i32 [[B]], [[Y:%.*]] +; CHECK-NEXT: [[TMP1:%.*]] = zext i1 [[COND]] to i32 +; CHECK-NEXT: [[C:%.*]] = sub i32 [[Y:%.*]], [[TMP1]] ; CHECK-NEXT: ret i32 [[C]] ; %b = add i32 %y, -1 @@ -707,8 +707,8 @@ define i32 @test42(i32 %x, i32 %y) { define <2 x i32> @test42vec(<2 x i32> %x, <2 x i32> %y) { ; CHECK-LABEL: @test42vec( ; CHECK-NEXT: [[COND:%.*]] = icmp eq <2 x i32> [[X:%.*]], zeroinitializer -; CHECK-NEXT: [[B:%.*]] = sext <2 x i1> [[COND]] to <2 x i32> -; CHECK-NEXT: [[C:%.*]] = add <2 x i32> [[B]], [[Y:%.*]] +; CHECK-NEXT: [[TMP1:%.*]] = zext <2 x i1> [[COND]] to <2 x i32> +; CHECK-NEXT: [[C:%.*]] = sub <2 x i32> [[Y:%.*]], [[TMP1]] ; CHECK-NEXT: ret <2 x i32> [[C]] ; %b = add <2 x i32> %y, diff --git a/test/Transforms/InstCombine/zext-bool-add-sub.ll b/test/Transforms/InstCombine/zext-bool-add-sub.ll index d009aa9ed97..86c20697288 100644 --- a/test/Transforms/InstCombine/zext-bool-add-sub.ll +++ b/test/Transforms/InstCombine/zext-bool-add-sub.ll @@ -5,9 +5,9 @@ define i32 @a(i1 zeroext %x, i1 zeroext %y) { ; CHECK-LABEL: @a( -; CHECK-NEXT: [[CONV3_NEG:%.*]] = sext i1 [[Y:%.*]] to i32 ; CHECK-NEXT: [[SUB:%.*]] = select i1 [[X:%.*]], i32 2, i32 1 -; CHECK-NEXT: [[ADD:%.*]] = add nsw i32 [[SUB]], [[CONV3_NEG]] +; CHECK-NEXT: [[TMP1:%.*]] = zext i1 [[Y:%.*]] to i32 +; CHECK-NEXT: [[ADD:%.*]] = sub nsw i32 [[SUB]], [[TMP1]] ; CHECK-NEXT: ret i32 [[ADD]] ; %conv = zext i1 %x to i32 @@ -317,8 +317,8 @@ define i8 @sext_sub_nuw(i8 %x, i1 %y) { define i32 @sextbool_add(i1 %c, i32 %x) { ; CHECK-LABEL: @sextbool_add( -; CHECK-NEXT: [[B:%.*]] = sext i1 [[C:%.*]] to i32 -; CHECK-NEXT: [[S:%.*]] = add i32 [[B]], [[X:%.*]] +; CHECK-NEXT: [[TMP1:%.*]] = zext i1 [[C:%.*]] to i32 +; CHECK-NEXT: [[S:%.*]] = sub i32 [[X:%.*]], [[TMP1]] ; CHECK-NEXT: ret i32 [[S]] ; %b = sext i1 %c to i32 @@ -329,8 +329,8 @@ define i32 @sextbool_add(i1 %c, i32 %x) { define i32 @sextbool_add_commute(i1 %c, i32 %px) { ; CHECK-LABEL: @sextbool_add_commute( ; CHECK-NEXT: [[X:%.*]] = urem i32 [[PX:%.*]], 42 -; CHECK-NEXT: [[B:%.*]] = sext i1 [[C:%.*]] to i32 -; CHECK-NEXT: [[S:%.*]] = add nsw i32 [[X]], [[B]] +; CHECK-NEXT: [[TMP1:%.*]] = zext i1 [[C:%.*]] to i32 +; CHECK-NEXT: [[S:%.*]] = sub nsw i32 [[X]], [[TMP1]] ; CHECK-NEXT: ret i32 [[S]] ; %x = urem i32 %px, 42 ; thwart complexity-based canonicalization @@ -358,8 +358,8 @@ define i32 @sextbool_add_uses(i1 %c, i32 %x) { define <4 x i32> @sextbool_add_vector(<4 x i1> %c, <4 x i32> %x) { ; CHECK-LABEL: @sextbool_add_vector( -; CHECK-NEXT: [[B:%.*]] = sext <4 x i1> [[C:%.*]] to <4 x i32> -; CHECK-NEXT: [[S:%.*]] = add <4 x i32> [[B]], [[X:%.*]] +; CHECK-NEXT: [[TMP1:%.*]] = zext <4 x i1> [[C:%.*]] to <4 x i32> +; CHECK-NEXT: [[S:%.*]] = sub <4 x i32> [[X:%.*]], [[TMP1]] ; CHECK-NEXT: ret <4 x i32> [[S]] ; %b = sext <4 x i1> %c to <4 x i32>