Author: Nikita Popov Date: 2021-01-03T18:51:49+01:00 New Revision: f094d65beaa492e845b03561eddd75b5be653a01
URL: https://github.com/llvm/llvm-project/commit/f094d65beaa492e845b03561eddd75b5be653a01 DIFF: https://github.com/llvm/llvm-project/commit/f094d65beaa492e845b03561eddd75b5be653a01.diff LOG: [InstSimplify] Fix addo/subo with undef (PR43188) We can't fold the first result to undef, because not all values may be reachable under the constraint that no overflow occurred. Use the same folds we do for saturated math instead. Proofs: uaddo: https://alive2.llvm.org/ce/z/zf55N_ saddo: https://alive2.llvm.org/ce/z/a_xPgS usubo: https://alive2.llvm.org/ce/z/DmRqwt ssubo: https://alive2.llvm.org/ce/z/8ag7U- Added: Modified: llvm/lib/Analysis/InstructionSimplify.cpp llvm/test/Transforms/InstCombine/with_overflow.ll llvm/test/Transforms/InstSimplify/call.ll Removed: ################################################################################ diff --git a/llvm/lib/Analysis/InstructionSimplify.cpp b/llvm/lib/Analysis/InstructionSimplify.cpp index 16b5fd5436f9..4706969eafc0 100644 --- a/llvm/lib/Analysis/InstructionSimplify.cpp +++ b/llvm/lib/Analysis/InstructionSimplify.cpp @@ -5444,19 +5444,19 @@ static Value *simplifyBinaryIntrinsic(Function *F, Value *Op0, Value *Op1, case Intrinsic::usub_with_overflow: case Intrinsic::ssub_with_overflow: // X - X -> { 0, false } - if (Op0 == Op1) + // X - undef -> { 0, false } + // undef - X -> { 0, false } + if (Op0 == Op1 || Q.isUndefValue(Op0) || Q.isUndefValue(Op1)) return Constant::getNullValue(ReturnType); - LLVM_FALLTHROUGH; + break; case Intrinsic::uadd_with_overflow: case Intrinsic::sadd_with_overflow: - // X - undef -> { undef, false } - // undef - X -> { undef, false } - // X + undef -> { undef, false } - // undef + x -> { undef, false } + // X + undef -> { -1, false } + // undef + x -> { -1, false } if (Q.isUndefValue(Op0) || Q.isUndefValue(Op1)) { return ConstantStruct::get( cast<StructType>(ReturnType), - {UndefValue::get(ReturnType->getStructElementType(0)), + {Constant::getAllOnesValue(ReturnType->getStructElementType(0)), Constant::getNullValue(ReturnType->getStructElementType(1))}); } break; diff --git a/llvm/test/Transforms/InstCombine/with_overflow.ll b/llvm/test/Transforms/InstCombine/with_overflow.ll index 84b5042e6186..4553c9f56965 100644 --- a/llvm/test/Transforms/InstCombine/with_overflow.ll +++ b/llvm/test/Transforms/InstCombine/with_overflow.ll @@ -61,7 +61,7 @@ define i8 @uaddtest3(i8 %A, i8 %B, i1* %overflowPtr) { define i8 @uaddtest4(i8 %A, i1* %overflowPtr) { ; CHECK-LABEL: @uaddtest4( ; CHECK-NEXT: store i1 false, i1* [[OVERFLOWPTR:%.*]], align 1 -; CHECK-NEXT: ret i8 undef +; CHECK-NEXT: ret i8 -1 ; %x = call { i8, i1 } @llvm.uadd.with.overflow.i8(i8 undef, i8 %A) %y = extractvalue { i8, i1 } %x, 0 diff --git a/llvm/test/Transforms/InstSimplify/call.ll b/llvm/test/Transforms/InstSimplify/call.ll index 841582ab8974..bb7410ada7d5 100644 --- a/llvm/test/Transforms/InstSimplify/call.ll +++ b/llvm/test/Transforms/InstSimplify/call.ll @@ -29,7 +29,7 @@ define i8 @test_uadd2() { define {i8, i1} @test_uadd3(i8 %v) { ; CHECK-LABEL: @test_uadd3( -; CHECK-NEXT: ret { i8, i1 } { i8 undef, i1 false } +; CHECK-NEXT: ret { i8, i1 } { i8 -1, i1 false } ; %result = call {i8, i1} @llvm.uadd.with.overflow.i8(i8 %v, i8 undef) ret {i8, i1} %result @@ -37,7 +37,7 @@ define {i8, i1} @test_uadd3(i8 %v) { define {i8, i1} @test_uadd3_poison(i8 %v) { ; CHECK-LABEL: @test_uadd3_poison( -; CHECK-NEXT: ret { i8, i1 } { i8 undef, i1 false } +; CHECK-NEXT: ret { i8, i1 } { i8 -1, i1 false } ; %result = call {i8, i1} @llvm.uadd.with.overflow.i8(i8 %v, i8 poison) ret {i8, i1} %result @@ -45,7 +45,7 @@ define {i8, i1} @test_uadd3_poison(i8 %v) { define {i8, i1} @test_uadd4(i8 %v) { ; CHECK-LABEL: @test_uadd4( -; CHECK-NEXT: ret { i8, i1 } { i8 undef, i1 false } +; CHECK-NEXT: ret { i8, i1 } { i8 -1, i1 false } ; %result = call {i8, i1} @llvm.uadd.with.overflow.i8(i8 undef, i8 %v) ret {i8, i1} %result @@ -53,7 +53,7 @@ define {i8, i1} @test_uadd4(i8 %v) { define {i8, i1} @test_uadd4_poison(i8 %v) { ; CHECK-LABEL: @test_uadd4_poison( -; CHECK-NEXT: ret { i8, i1 } { i8 undef, i1 false } +; CHECK-NEXT: ret { i8, i1 } { i8 -1, i1 false } ; %result = call {i8, i1} @llvm.uadd.with.overflow.i8(i8 poison, i8 %v) ret {i8, i1} %result @@ -79,7 +79,7 @@ define i8 @test_sadd2() { define {i8, i1} @test_sadd3(i8 %v) { ; CHECK-LABEL: @test_sadd3( -; CHECK-NEXT: ret { i8, i1 } { i8 undef, i1 false } +; CHECK-NEXT: ret { i8, i1 } { i8 -1, i1 false } ; %result = call {i8, i1} @llvm.sadd.with.overflow.i8(i8 %v, i8 undef) ret {i8, i1} %result @@ -87,7 +87,7 @@ define {i8, i1} @test_sadd3(i8 %v) { define {i8, i1} @test_sadd3_poison(i8 %v) { ; CHECK-LABEL: @test_sadd3_poison( -; CHECK-NEXT: ret { i8, i1 } { i8 undef, i1 false } +; CHECK-NEXT: ret { i8, i1 } { i8 -1, i1 false } ; %result = call {i8, i1} @llvm.sadd.with.overflow.i8(i8 %v, i8 poison) ret {i8, i1} %result @@ -95,7 +95,7 @@ define {i8, i1} @test_sadd3_poison(i8 %v) { define {i8, i1} @test_sadd4(i8 %v) { ; CHECK-LABEL: @test_sadd4( -; CHECK-NEXT: ret { i8, i1 } { i8 undef, i1 false } +; CHECK-NEXT: ret { i8, i1 } { i8 -1, i1 false } ; %result = call {i8, i1} @llvm.sadd.with.overflow.i8(i8 undef, i8 %v) ret {i8, i1} %result @@ -103,7 +103,7 @@ define {i8, i1} @test_sadd4(i8 %v) { define {i8, i1} @test_sadd4_poison(i8 %v) { ; CHECK-LABEL: @test_sadd4_poison( -; CHECK-NEXT: ret { i8, i1 } { i8 undef, i1 false } +; CHECK-NEXT: ret { i8, i1 } { i8 -1, i1 false } ; %result = call {i8, i1} @llvm.sadd.with.overflow.i8(i8 poison, i8 %v) ret {i8, i1} %result @@ -119,7 +119,7 @@ define {i8, i1} @test_usub1(i8 %V) { define {i8, i1} @test_usub2(i8 %V) { ; CHECK-LABEL: @test_usub2( -; CHECK-NEXT: ret { i8, i1 } { i8 undef, i1 false } +; CHECK-NEXT: ret { i8, i1 } zeroinitializer ; %x = call {i8, i1} @llvm.usub.with.overflow.i8(i8 %V, i8 undef) ret {i8, i1} %x @@ -127,7 +127,7 @@ define {i8, i1} @test_usub2(i8 %V) { define {i8, i1} @test_usub2_poison(i8 %V) { ; CHECK-LABEL: @test_usub2_poison( -; CHECK-NEXT: ret { i8, i1 } { i8 undef, i1 false } +; CHECK-NEXT: ret { i8, i1 } zeroinitializer ; %x = call {i8, i1} @llvm.usub.with.overflow.i8(i8 %V, i8 poison) ret {i8, i1} %x @@ -135,7 +135,7 @@ define {i8, i1} @test_usub2_poison(i8 %V) { define {i8, i1} @test_usub3(i8 %V) { ; CHECK-LABEL: @test_usub3( -; CHECK-NEXT: ret { i8, i1 } { i8 undef, i1 false } +; CHECK-NEXT: ret { i8, i1 } zeroinitializer ; %x = call {i8, i1} @llvm.usub.with.overflow.i8(i8 undef, i8 %V) ret {i8, i1} %x @@ -143,7 +143,7 @@ define {i8, i1} @test_usub3(i8 %V) { define {i8, i1} @test_usub3_poison(i8 %V) { ; CHECK-LABEL: @test_usub3_poison( -; CHECK-NEXT: ret { i8, i1 } { i8 undef, i1 false } +; CHECK-NEXT: ret { i8, i1 } zeroinitializer ; %x = call {i8, i1} @llvm.usub.with.overflow.i8(i8 poison, i8 %V) ret {i8, i1} %x @@ -159,7 +159,7 @@ define {i8, i1} @test_ssub1(i8 %V) { define {i8, i1} @test_ssub2(i8 %V) { ; CHECK-LABEL: @test_ssub2( -; CHECK-NEXT: ret { i8, i1 } { i8 undef, i1 false } +; CHECK-NEXT: ret { i8, i1 } zeroinitializer ; %x = call {i8, i1} @llvm.ssub.with.overflow.i8(i8 %V, i8 undef) ret {i8, i1} %x @@ -167,7 +167,7 @@ define {i8, i1} @test_ssub2(i8 %V) { define {i8, i1} @test_ssub2_poison(i8 %V) { ; CHECK-LABEL: @test_ssub2_poison( -; CHECK-NEXT: ret { i8, i1 } { i8 undef, i1 false } +; CHECK-NEXT: ret { i8, i1 } zeroinitializer ; %x = call {i8, i1} @llvm.ssub.with.overflow.i8(i8 %V, i8 poison) ret {i8, i1} %x @@ -175,7 +175,7 @@ define {i8, i1} @test_ssub2_poison(i8 %V) { define {i8, i1} @test_ssub3(i8 %V) { ; CHECK-LABEL: @test_ssub3( -; CHECK-NEXT: ret { i8, i1 } { i8 undef, i1 false } +; CHECK-NEXT: ret { i8, i1 } zeroinitializer ; %x = call {i8, i1} @llvm.ssub.with.overflow.i8(i8 undef, i8 %V) ret {i8, i1} %x @@ -183,7 +183,7 @@ define {i8, i1} @test_ssub3(i8 %V) { define {i8, i1} @test_ssub3_poison(i8 %V) { ; CHECK-LABEL: @test_ssub3_poison( -; CHECK-NEXT: ret { i8, i1 } { i8 undef, i1 false } +; CHECK-NEXT: ret { i8, i1 } zeroinitializer ; %x = call {i8, i1} @llvm.ssub.with.overflow.i8(i8 poison, i8 %V) ret {i8, i1} %x _______________________________________________ llvm-branch-commits mailing list llvm-branch-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits