llvm.org GIT mirror llvm / d09f140
[InstSimplify] Fix addo/subo undef folds (PR42209) Fix folds of addo and subo with an undef operand to be: `@llvm.{u,s}{add,sub}.with.overflow` all fold to `{ undef, false }`, as per LLVM undef rules. Same for commuted variants. Based on the original version of the patch by @nikic. Fixes [[ https://bugs.llvm.org/show_bug.cgi?id=42209 | PR42209 ]] Differential Revision: https://reviews.llvm.org/D63065 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@363522 91177308-0d34-0410-b5e6-96231b3b80d8 Roman Lebedev 3 months ago
3 changed file(s) with 20 addition(s) and 16 deletion(s). Raw diff Collapse all Expand all
48424842 // X - X -> { 0, false }
48434843 if (Op0 == Op1)
48444844 return Constant::getNullValue(ReturnType);
4845 // X - undef -> undef
4846 // undef - X -> undef
4847 if (isa(Op0) || isa(Op1))
4848 return UndefValue::get(ReturnType);
4849 break;
4845 LLVM_FALLTHROUGH;
48504846 case Intrinsic::uadd_with_overflow:
48514847 case Intrinsic::sadd_with_overflow:
4852 // X + undef -> undef
4853 if (isa(Op0) || isa(Op1))
4854 return UndefValue::get(ReturnType);
4848 // X - undef -> { undef, false }
4849 // undef - X -> { undef, false }
4850 // X + undef -> { undef, false }
4851 // undef + x -> { undef, false }
4852 if (isa(Op0) || isa(Op1)) {
4853 return ConstantStruct::get(
4854 cast(ReturnType),
4855 {UndefValue::get(ReturnType->getStructElementType(0)),
4856 Constant::getNullValue(ReturnType->getStructElementType(1))});
4857 }
48554858 break;
48564859 case Intrinsic::umul_with_overflow:
48574860 case Intrinsic::smul_with_overflow:
5959
6060 define i8 @uaddtest4(i8 %A, i1* %overflowPtr) {
6161 ; CHECK-LABEL: @uaddtest4(
62 ; CHECK-NEXT: store i1 false, i1* [[OVERFLOWPTR:%.*]], align 1
6263 ; CHECK-NEXT: ret i8 undef
6364 ;
6465 %x = call { i8, i1 } @llvm.uadd.with.overflow.i8(i8 undef, i8 %A)
2828
2929 define {i8, i1} @test_uadd3(i8 %v) {
3030 ; CHECK-LABEL: @test_uadd3(
31 ; CHECK-NEXT: ret { i8, i1 } undef
31 ; CHECK-NEXT: ret { i8, i1 } { i8 undef, i1 false }
3232 ;
3333 %result = call {i8, i1} @llvm.uadd.with.overflow.i8(i8 %v, i8 undef)
3434 ret {i8, i1} %result
3636
3737 define {i8, i1} @test_uadd4(i8 %v) {
3838 ; CHECK-LABEL: @test_uadd4(
39 ; CHECK-NEXT: ret { i8, i1 } undef
39 ; CHECK-NEXT: ret { i8, i1 } { i8 undef, i1 false }
4040 ;
4141 %result = call {i8, i1} @llvm.uadd.with.overflow.i8(i8 undef, i8 %v)
4242 ret {i8, i1} %result
6262
6363 define {i8, i1} @test_sadd3(i8 %v) {
6464 ; CHECK-LABEL: @test_sadd3(
65 ; CHECK-NEXT: ret { i8, i1 } undef
65 ; CHECK-NEXT: ret { i8, i1 } { i8 undef, i1 false }
6666 ;
6767 %result = call {i8, i1} @llvm.sadd.with.overflow.i8(i8 %v, i8 undef)
6868 ret {i8, i1} %result
7070
7171 define {i8, i1} @test_sadd4(i8 %v) {
7272 ; CHECK-LABEL: @test_sadd4(
73 ; CHECK-NEXT: ret { i8, i1 } undef
73 ; CHECK-NEXT: ret { i8, i1 } { i8 undef, i1 false }
7474 ;
7575 %result = call {i8, i1} @llvm.sadd.with.overflow.i8(i8 undef, i8 %v)
7676 ret {i8, i1} %result
8686
8787 define {i8, i1} @test_usub2(i8 %V) {
8888 ; CHECK-LABEL: @test_usub2(
89 ; CHECK-NEXT: ret { i8, i1 } undef
89 ; CHECK-NEXT: ret { i8, i1 } { i8 undef, i1 false }
9090 ;
9191 %x = call {i8, i1} @llvm.usub.with.overflow.i8(i8 %V, i8 undef)
9292 ret {i8, i1} %x
9494
9595 define {i8, i1} @test_usub3(i8 %V) {
9696 ; CHECK-LABEL: @test_usub3(
97 ; CHECK-NEXT: ret { i8, i1 } undef
97 ; CHECK-NEXT: ret { i8, i1 } { i8 undef, i1 false }
9898 ;
9999 %x = call {i8, i1} @llvm.usub.with.overflow.i8(i8 undef, i8 %V)
100100 ret {i8, i1} %x
110110
111111 define {i8, i1} @test_ssub2(i8 %V) {
112112 ; CHECK-LABEL: @test_ssub2(
113 ; CHECK-NEXT: ret { i8, i1 } undef
113 ; CHECK-NEXT: ret { i8, i1 } { i8 undef, i1 false }
114114 ;
115115 %x = call {i8, i1} @llvm.ssub.with.overflow.i8(i8 %V, i8 undef)
116116 ret {i8, i1} %x
118118
119119 define {i8, i1} @test_ssub3(i8 %V) {
120120 ; CHECK-LABEL: @test_ssub3(
121 ; CHECK-NEXT: ret { i8, i1 } undef
121 ; CHECK-NEXT: ret { i8, i1 } { i8 undef, i1 false }
122122 ;
123123 %x = call {i8, i1} @llvm.ssub.with.overflow.i8(i8 undef, i8 %V)
124124 ret {i8, i1} %x