aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorYingwei Zheng <dtcxzyw2333@gmail.com>2023-11-17 14:02:47 +0800
committerGitHub <noreply@github.com>2023-11-17 14:02:47 +0800
commit865c1fda6f3e258b47a4f7992bb19ca2e9edcfa1 (patch)
treeeabe757c8c51468016e38d14c5e80bd2e07ce8b7
parent5353d3f509814a44093a61c2725fdfe7273aa25a (diff)
downloadllvm-865c1fda6f3e258b47a4f7992bb19ca2e9edcfa1.zip
llvm-865c1fda6f3e258b47a4f7992bb19ca2e9edcfa1.tar.gz
llvm-865c1fda6f3e258b47a4f7992bb19ca2e9edcfa1.tar.bz2
[InstCombine] Preserve NSW flags for neg instructions (#72548)
Alive2: https://alive2.llvm.org/ce/z/F9HG3M This missed optimization is discovered with the help of https://github.com/AliveToolkit/alive2/pull/962.
-rw-r--r--llvm/lib/Transforms/InstCombine/InstCombineMulDivRem.cpp4
-rw-r--r--llvm/test/Transforms/InstCombine/div.ll16
-rw-r--r--llvm/test/Transforms/InstCombine/sdiv-exact-by-negative-power-of-two.ll6
3 files changed, 13 insertions, 13 deletions
diff --git a/llvm/lib/Transforms/InstCombine/InstCombineMulDivRem.cpp b/llvm/lib/Transforms/InstCombine/InstCombineMulDivRem.cpp
index d6fac88..4015672 100644
--- a/llvm/lib/Transforms/InstCombine/InstCombineMulDivRem.cpp
+++ b/llvm/lib/Transforms/InstCombine/InstCombineMulDivRem.cpp
@@ -1433,7 +1433,7 @@ Instruction *InstCombinerImpl::visitSDiv(BinaryOperator &I) {
// sdiv Op0, (sext i1 X) --> -Op0 (because if X is 0, the op is undefined)
if (match(Op1, m_AllOnes()) ||
(match(Op1, m_SExt(m_Value(X))) && X->getType()->isIntOrIntVectorTy(1)))
- return BinaryOperator::CreateNeg(Op0);
+ return BinaryOperator::CreateNSWNeg(Op0);
// X / INT_MIN --> X == INT_MIN
if (match(Op1, m_SignMask()))
@@ -1456,7 +1456,7 @@ Instruction *InstCombinerImpl::visitSDiv(BinaryOperator &I) {
Constant *NegPow2C = ConstantExpr::getNeg(cast<Constant>(Op1));
Constant *C = ConstantExpr::getExactLogBase2(NegPow2C);
Value *Ashr = Builder.CreateAShr(Op0, C, I.getName() + ".neg", true);
- return BinaryOperator::CreateNeg(Ashr);
+ return BinaryOperator::CreateNSWNeg(Ashr);
}
}
diff --git a/llvm/test/Transforms/InstCombine/div.ll b/llvm/test/Transforms/InstCombine/div.ll
index 844b357..cd17d10 100644
--- a/llvm/test/Transforms/InstCombine/div.ll
+++ b/llvm/test/Transforms/InstCombine/div.ll
@@ -22,7 +22,7 @@ define i32 @test2(i32 %A) {
define i32 @sdiv_by_minus1(i32 %A) {
; CHECK-LABEL: @sdiv_by_minus1(
-; CHECK-NEXT: [[B:%.*]] = sub i32 0, [[A:%.*]]
+; CHECK-NEXT: [[B:%.*]] = sub nsw i32 0, [[A:%.*]]
; CHECK-NEXT: ret i32 [[B]]
;
%B = sdiv i32 %A, -1
@@ -31,7 +31,7 @@ define i32 @sdiv_by_minus1(i32 %A) {
define <2 x i64> @sdiv_by_minus1_vec(<2 x i64> %x) {
; CHECK-LABEL: @sdiv_by_minus1_vec(
-; CHECK-NEXT: [[DIV:%.*]] = sub <2 x i64> zeroinitializer, [[X:%.*]]
+; CHECK-NEXT: [[DIV:%.*]] = sub nsw <2 x i64> zeroinitializer, [[X:%.*]]
; CHECK-NEXT: ret <2 x i64> [[DIV]]
;
%div = sdiv <2 x i64> %x, <i64 -1, i64 -1>
@@ -48,7 +48,7 @@ define <2 x i64> @sdiv_by_minus1_vec_poison_elt(<2 x i64> %x) {
define i32 @sdiv_by_sext_minus1(i1 %x, i32 %y) {
; CHECK-LABEL: @sdiv_by_sext_minus1(
-; CHECK-NEXT: [[DIV:%.*]] = sub i32 0, [[Y:%.*]]
+; CHECK-NEXT: [[DIV:%.*]] = sub nsw i32 0, [[Y:%.*]]
; CHECK-NEXT: ret i32 [[DIV]]
;
%sext = sext i1 %x to i32
@@ -58,7 +58,7 @@ define i32 @sdiv_by_sext_minus1(i1 %x, i32 %y) {
define <2 x i32> @sdiv_by_sext_minus1_vec(<2 x i1> %x, <2 x i32> %y) {
; CHECK-LABEL: @sdiv_by_sext_minus1_vec(
-; CHECK-NEXT: [[DIV:%.*]] = sub <2 x i32> zeroinitializer, [[Y:%.*]]
+; CHECK-NEXT: [[DIV:%.*]] = sub nsw <2 x i32> zeroinitializer, [[Y:%.*]]
; CHECK-NEXT: ret <2 x i32> [[DIV]]
;
%sext = sext <2 x i1> %x to <2 x i32>
@@ -1308,8 +1308,8 @@ define i32 @udiv_select_of_constants_divisor(i1 %b, i32 %x) {
define i1 @sdiv_one_icmpeq_one(i32 %x) {
; CHECK-LABEL: @sdiv_one_icmpeq_one(
; CHECK-NEXT: [[X_FR:%.*]] = freeze i32 [[X:%.*]]
-; CHECK-NEXT: [[B:%.*]] = icmp eq i32 [[X_FR]], 1
-; CHECK-NEXT: ret i1 [[B]]
+; CHECK-NEXT: [[B1:%.*]] = icmp eq i32 [[X_FR]], 1
+; CHECK-NEXT: ret i1 [[B1]]
;
%A = sdiv i32 1, %x
%B = icmp eq i32 %A, 1
@@ -1319,8 +1319,8 @@ define i1 @sdiv_one_icmpeq_one(i32 %x) {
define i1 @sdiv_one_icmpeq_negone(i32 %x) {
; CHECK-LABEL: @sdiv_one_icmpeq_negone(
; CHECK-NEXT: [[X_FR:%.*]] = freeze i32 [[X:%.*]]
-; CHECK-NEXT: [[B:%.*]] = icmp eq i32 [[X_FR]], -1
-; CHECK-NEXT: ret i1 [[B]]
+; CHECK-NEXT: [[B1:%.*]] = icmp eq i32 [[X_FR]], -1
+; CHECK-NEXT: ret i1 [[B1]]
;
%A = sdiv i32 1, %x
%B = icmp eq i32 %A, -1
diff --git a/llvm/test/Transforms/InstCombine/sdiv-exact-by-negative-power-of-two.ll b/llvm/test/Transforms/InstCombine/sdiv-exact-by-negative-power-of-two.ll
index 81f22bb..3451c5e 100644
--- a/llvm/test/Transforms/InstCombine/sdiv-exact-by-negative-power-of-two.ll
+++ b/llvm/test/Transforms/InstCombine/sdiv-exact-by-negative-power-of-two.ll
@@ -38,7 +38,7 @@ define <2 x i8> @t2_vec_splat(<2 x i8> %x) {
define <2 x i8> @t3_vec(<2 x i8> %x) {
; CHECK-LABEL: @t3_vec(
; CHECK-NEXT: [[DIV_NEG:%.*]] = ashr exact <2 x i8> [[X:%.*]], <i8 5, i8 4>
-; CHECK-NEXT: [[DIV:%.*]] = sub <2 x i8> zeroinitializer, [[DIV_NEG]]
+; CHECK-NEXT: [[DIV:%.*]] = sub nsw <2 x i8> zeroinitializer, [[DIV_NEG]]
; CHECK-NEXT: ret <2 x i8> [[DIV]]
;
%div = sdiv exact <2 x i8> %x, <i8 -32, i8 -16>
@@ -76,8 +76,8 @@ define i8 @prove_exact_with_high_mask(i8 %x, i8 %y) {
define i8 @prove_exact_with_high_mask_limit(i8 %x, i8 %y) {
; CHECK-LABEL: @prove_exact_with_high_mask_limit(
-; CHECK-NEXT: [[A:%.*]] = ashr i8 [[X:%.*]], 5
-; CHECK-NEXT: [[D:%.*]] = sub nsw i8 0, [[A]]
+; CHECK-NEXT: [[D_NEG:%.*]] = ashr i8 [[X:%.*]], 5
+; CHECK-NEXT: [[D:%.*]] = sub nsw i8 0, [[D_NEG]]
; CHECK-NEXT: ret i8 [[D]]
;
%a = and i8 %x, -32