summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--llvm/lib/Transforms/InstCombine/InstCombineAddSub.cpp18
-rw-r--r--llvm/test/Transforms/InstCombine/apint-shift.ll7
-rw-r--r--llvm/test/Transforms/InstCombine/logical-select.ll4
-rw-r--r--llvm/test/Transforms/InstCombine/select.ll8
-rw-r--r--llvm/test/Transforms/InstCombine/shift.ll19
-rw-r--r--llvm/test/Transforms/InstCombine/zext-bool-add-sub.ll20
6 files changed, 51 insertions, 25 deletions
diff --git a/llvm/lib/Transforms/InstCombine/InstCombineAddSub.cpp b/llvm/lib/Transforms/InstCombine/InstCombineAddSub.cpp
index 5b71f9d9c2e..ad42f3dabfe 100644
--- a/llvm/lib/Transforms/InstCombine/InstCombineAddSub.cpp
+++ b/llvm/lib/Transforms/InstCombine/InstCombineAddSub.cpp
@@ -890,6 +890,10 @@ Instruction *InstCombiner::foldAddWithConstant(BinaryOperator &Add) {
if (match(Op0, m_ZExt(m_Value(X))) &&
X->getType()->getScalarSizeInBits() == 1)
return SelectInst::Create(X, AddOne(Op1C), Op1);
+ // sext(bool) + C -> bool ? C - 1 : C
+ if (match(Op0, m_SExt(m_Value(X))) &&
+ X->getType()->getScalarSizeInBits() == 1)
+ return SelectInst::Create(X, SubOne(Op1C), Op1);
// ~X + C --> (C-1) - X
if (match(Op0, m_Not(m_Value(X))))
@@ -1288,12 +1292,6 @@ 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);
@@ -1923,6 +1921,14 @@ Instruction *InstCombiner::visitSub(BinaryOperator &I) {
Add->setHasNoSignedWrap(I.hasNoSignedWrap());
return Add;
}
+ // sub [nsw] X, zext(bool Y) -> add [nsw] X, sext(bool Y)
+ // 'nuw' is dropped in favor of the canonical form.
+ if (match(Op1, m_ZExt(m_Value(Y))) && Y->getType()->isIntOrIntVectorTy(1)) {
+ Value *Sext = Builder.CreateSExt(Y, I.getType());
+ BinaryOperator *Add = BinaryOperator::CreateAdd(Op0, Sext);
+ Add->setHasNoSignedWrap(I.hasNoSignedWrap());
+ return Add;
+ }
// X - A*-B -> X + A*B
// X - -A*B -> X + A*B
diff --git a/llvm/test/Transforms/InstCombine/apint-shift.ll b/llvm/test/Transforms/InstCombine/apint-shift.ll
index 495d9d6d8b2..8f7e36ca633 100644
--- a/llvm/test/Transforms/InstCombine/apint-shift.ll
+++ b/llvm/test/Transforms/InstCombine/apint-shift.ll
@@ -533,8 +533,11 @@ define i177 @ossfuzz_9880(i177 %X) {
; CHECK-LABEL: @ossfuzz_9880(
; 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: [[TMP1:%.*]] = icmp eq i177 [[L1]], -1
+; CHECK-NEXT: [[TMP2:%.*]] = sext i1 [[TMP1]] to i177
+; CHECK-NEXT: [[B14:%.*]] = add i177 [[L1]], [[TMP2]]
+; CHECK-NEXT: [[TMP3:%.*]] = icmp eq i177 [[B14]], -1
+; CHECK-NEXT: [[B1:%.*]] = zext i1 [[TMP3]] to i177
; CHECK-NEXT: ret i177 [[B1]]
;
%A = alloca i177
diff --git a/llvm/test/Transforms/InstCombine/logical-select.ll b/llvm/test/Transforms/InstCombine/logical-select.ll
index 3f02554e7de..82f72a8c666 100644
--- a/llvm/test/Transforms/InstCombine/logical-select.ll
+++ b/llvm/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:%.*]], <i1 true, i1 false, i1 false, i1 false>
+; CHECK-NEXT: [[MASK_FLIP1:%.*]] = sext <4 x i1> [[TMP1]] to <4 x i32>
; CHECK-NEXT: [[TMP2:%.*]] = xor <4 x i1> [[C]], <i1 false, i1 true, i1 true, i1 true>
; CHECK-NEXT: [[TMP3:%.*]] = select <4 x i1> [[TMP2]], <4 x i32> [[A:%.*]], <4 x i32> [[B:%.*]]
-; CHECK-NEXT: [[TMP4:%.*]] = zext <4 x i1> [[TMP1]] to <4 x i32>
-; CHECK-NEXT: [[ADD:%.*]] = sub <4 x i32> [[TMP3]], [[TMP4]]
+; CHECK-NEXT: [[ADD:%.*]] = add <4 x i32> [[TMP3]], [[MASK_FLIP1]]
; CHECK-NEXT: ret <4 x i32> [[ADD]]
;
%mask = sext <4 x i1> %c to <4 x i32>
diff --git a/llvm/test/Transforms/InstCombine/select.ll b/llvm/test/Transforms/InstCombine/select.ll
index 1a4a5d197a2..6a35d40ff19 100644
--- a/llvm/test/Transforms/InstCombine/select.ll
+++ b/llvm/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: [[TMP1:%.*]] = zext i1 [[COND]] to i32
-; CHECK-NEXT: [[C:%.*]] = sub i32 [[Y:%.*]], [[TMP1]]
+; CHECK-NEXT: [[B:%.*]] = sext i1 [[COND]] to i32
+; CHECK-NEXT: [[C:%.*]] = add i32 [[B]], [[Y:%.*]]
; 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: [[TMP1:%.*]] = zext <2 x i1> [[COND]] to <2 x i32>
-; CHECK-NEXT: [[C:%.*]] = sub <2 x i32> [[Y:%.*]], [[TMP1]]
+; CHECK-NEXT: [[B:%.*]] = sext <2 x i1> [[COND]] to <2 x i32>
+; CHECK-NEXT: [[C:%.*]] = add <2 x i32> [[B]], [[Y:%.*]]
; CHECK-NEXT: ret <2 x i32> [[C]]
;
%b = add <2 x i32> %y, <i32 -1, i32 -1>
diff --git a/llvm/test/Transforms/InstCombine/shift.ll b/llvm/test/Transforms/InstCombine/shift.ll
index 97871d18f91..822f915d566 100644
--- a/llvm/test/Transforms/InstCombine/shift.ll
+++ b/llvm/test/Transforms/InstCombine/shift.ll
@@ -1628,7 +1628,12 @@ define i32 @ashr_select_xor_false(i32 %x, i1 %cond) {
; https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=4871
define i177 @lshr_out_of_range(i177 %Y, i177** %A2) {
; CHECK-LABEL: @lshr_out_of_range(
-; CHECK-NEXT: store i177** [[A2:%.*]], i177*** undef, align 8
+; CHECK-NEXT: [[TMP1:%.*]] = icmp ne i177 [[Y:%.*]], -1
+; CHECK-NEXT: [[B4:%.*]] = sext i1 [[TMP1]] to i177
+; CHECK-NEXT: [[C8:%.*]] = icmp ult i177 [[B4]], [[Y]]
+; CHECK-NEXT: [[TMP2:%.*]] = sext i1 [[C8]] to i64
+; CHECK-NEXT: [[G18:%.*]] = getelementptr i177*, i177** [[A2:%.*]], i64 [[TMP2]]
+; CHECK-NEXT: store i177** [[G18]], i177*** undef, align 8
; CHECK-NEXT: ret i177 0
;
%B5 = udiv i177 %Y, -1
@@ -1649,6 +1654,18 @@ define i177 @lshr_out_of_range(i177 %Y, i177** %A2) {
; https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=5032
define void @ashr_out_of_range(i177* %A) {
; CHECK-LABEL: @ashr_out_of_range(
+; CHECK-NEXT: [[L:%.*]] = load i177, i177* [[A:%.*]], align 4
+; CHECK-NEXT: [[TMP1:%.*]] = icmp eq i177 [[L]], -1
+; CHECK-NEXT: [[B2:%.*]] = select i1 [[TMP1]], i64 -1, i64 -2
+; CHECK-NEXT: [[G11:%.*]] = getelementptr i177, i177* [[A]], i64 [[B2]]
+; CHECK-NEXT: [[L7:%.*]] = load i177, i177* [[G11]], align 4
+; CHECK-NEXT: [[B36:%.*]] = select i1 [[TMP1]], i177 0, i177 [[L7]]
+; CHECK-NEXT: [[C17:%.*]] = icmp sgt i177 [[B36]], [[L7]]
+; CHECK-NEXT: [[TMP2:%.*]] = sext i1 [[C17]] to i64
+; CHECK-NEXT: [[G62:%.*]] = getelementptr i177, i177* [[G11]], i64 [[TMP2]]
+; CHECK-NEXT: [[TMP3:%.*]] = icmp eq i177 [[L7]], -1
+; CHECK-NEXT: [[B28:%.*]] = select i1 [[TMP3]], i177 0, i177 [[L7]]
+; CHECK-NEXT: store i177 [[B28]], i177* [[G62]], align 4
; CHECK-NEXT: ret void
;
%L = load i177, i177* %A
diff --git a/llvm/test/Transforms/InstCombine/zext-bool-add-sub.ll b/llvm/test/Transforms/InstCombine/zext-bool-add-sub.ll
index 86c20697288..71fa9a79573 100644
--- a/llvm/test/Transforms/InstCombine/zext-bool-add-sub.ll
+++ b/llvm/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: [[TMP1:%.*]] = zext i1 [[Y:%.*]] to i32
-; CHECK-NEXT: [[ADD:%.*]] = sub nsw i32 [[SUB]], [[TMP1]]
+; CHECK-NEXT: [[ADD:%.*]] = add nsw i32 [[SUB]], [[CONV3_NEG]]
; 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: [[TMP1:%.*]] = zext i1 [[C:%.*]] to i32
-; CHECK-NEXT: [[S:%.*]] = sub i32 [[X:%.*]], [[TMP1]]
+; CHECK-NEXT: [[B:%.*]] = sext i1 [[C:%.*]] to i32
+; CHECK-NEXT: [[S:%.*]] = add i32 [[B]], [[X:%.*]]
; 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: [[TMP1:%.*]] = zext i1 [[C:%.*]] to i32
-; CHECK-NEXT: [[S:%.*]] = sub nsw i32 [[X]], [[TMP1]]
+; CHECK-NEXT: [[B:%.*]] = sext i1 [[C:%.*]] to i32
+; CHECK-NEXT: [[S:%.*]] = add nsw i32 [[X]], [[B]]
; 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: [[TMP1:%.*]] = zext <4 x i1> [[C:%.*]] to <4 x i32>
-; CHECK-NEXT: [[S:%.*]] = sub <4 x i32> [[X:%.*]], [[TMP1]]
+; CHECK-NEXT: [[B:%.*]] = sext <4 x i1> [[C:%.*]] to <4 x i32>
+; CHECK-NEXT: [[S:%.*]] = add <4 x i32> [[B]], [[X:%.*]]
; CHECK-NEXT: ret <4 x i32> [[S]]
;
%b = sext <4 x i1> %c to <4 x i32>
@@ -393,8 +393,8 @@ define i32 @zextbool_sub_uses(i1 %c, i32 %x) {
define <4 x i32> @zextbool_sub_vector(<4 x i1> %c, <4 x i32> %x) {
; CHECK-LABEL: @zextbool_sub_vector(
-; CHECK-NEXT: [[B:%.*]] = zext <4 x i1> [[C:%.*]] to <4 x i32>
-; CHECK-NEXT: [[S:%.*]] = sub <4 x i32> [[X:%.*]], [[B]]
+; CHECK-NEXT: [[TMP1:%.*]] = sext <4 x i1> [[C:%.*]] to <4 x i32>
+; CHECK-NEXT: [[S:%.*]] = add <4 x i32> [[TMP1]], [[X:%.*]]
; CHECK-NEXT: ret <4 x i32> [[S]]
;
%b = zext <4 x i1> %c to <4 x i32>
OpenPOWER on IntegriCloud