summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--llvm/lib/Analysis/InstructionSimplify.cpp19
-rw-r--r--llvm/test/Transforms/InstCombine/with_overflow.ll1
-rw-r--r--llvm/test/Transforms/InstSimplify/call.ll16
3 files changed, 20 insertions, 16 deletions
diff --git a/llvm/lib/Analysis/InstructionSimplify.cpp b/llvm/lib/Analysis/InstructionSimplify.cpp
index d0b9549d3ae..ba76c5b0479 100644
--- a/llvm/lib/Analysis/InstructionSimplify.cpp
+++ b/llvm/lib/Analysis/InstructionSimplify.cpp
@@ -4843,16 +4843,19 @@ static Value *simplifyBinaryIntrinsic(Function *F, Value *Op0, Value *Op1,
// X - X -> { 0, false }
if (Op0 == Op1)
return Constant::getNullValue(ReturnType);
- // X - undef -> undef
- // undef - X -> undef
- if (isa<UndefValue>(Op0) || isa<UndefValue>(Op1))
- return UndefValue::get(ReturnType);
- break;
+ LLVM_FALLTHROUGH;
case Intrinsic::uadd_with_overflow:
case Intrinsic::sadd_with_overflow:
- // X + undef -> undef
- if (isa<UndefValue>(Op0) || isa<UndefValue>(Op1))
- return UndefValue::get(ReturnType);
+ // X - undef -> { undef, false }
+ // undef - X -> { undef, false }
+ // X + undef -> { undef, false }
+ // undef + x -> { undef, false }
+ if (isa<UndefValue>(Op0) || isa<UndefValue>(Op1)) {
+ return ConstantStruct::get(
+ cast<StructType>(ReturnType),
+ {UndefValue::get(ReturnType->getStructElementType(0)),
+ Constant::getNullValue(ReturnType->getStructElementType(1))});
+ }
break;
case Intrinsic::umul_with_overflow:
case Intrinsic::smul_with_overflow:
diff --git a/llvm/test/Transforms/InstCombine/with_overflow.ll b/llvm/test/Transforms/InstCombine/with_overflow.ll
index b15e37ce6e0..04e8097ca7d 100644
--- a/llvm/test/Transforms/InstCombine/with_overflow.ll
+++ b/llvm/test/Transforms/InstCombine/with_overflow.ll
@@ -60,6 +60,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
;
%x = call { i8, i1 } @llvm.uadd.with.overflow.i8(i8 undef, i8 %A)
diff --git a/llvm/test/Transforms/InstSimplify/call.ll b/llvm/test/Transforms/InstSimplify/call.ll
index 0771e4453e3..27497e5e862 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 } undef
+; CHECK-NEXT: ret { i8, i1 } { i8 undef, 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_uadd4(i8 %v) {
; CHECK-LABEL: @test_uadd4(
-; CHECK-NEXT: ret { i8, i1 } undef
+; CHECK-NEXT: ret { i8, i1 } { i8 undef, i1 false }
;
%result = call {i8, i1} @llvm.uadd.with.overflow.i8(i8 undef, i8 %v)
ret {i8, i1} %result
@@ -63,7 +63,7 @@ define i8 @test_sadd2() {
define {i8, i1} @test_sadd3(i8 %v) {
; CHECK-LABEL: @test_sadd3(
-; CHECK-NEXT: ret { i8, i1 } undef
+; CHECK-NEXT: ret { i8, i1 } { i8 undef, i1 false }
;
%result = call {i8, i1} @llvm.sadd.with.overflow.i8(i8 %v, i8 undef)
ret {i8, i1} %result
@@ -71,7 +71,7 @@ define {i8, i1} @test_sadd3(i8 %v) {
define {i8, i1} @test_sadd4(i8 %v) {
; CHECK-LABEL: @test_sadd4(
-; CHECK-NEXT: ret { i8, i1 } undef
+; CHECK-NEXT: ret { i8, i1 } { i8 undef, i1 false }
;
%result = call {i8, i1} @llvm.sadd.with.overflow.i8(i8 undef, i8 %v)
ret {i8, i1} %result
@@ -87,7 +87,7 @@ define {i8, i1} @test_usub1(i8 %V) {
define {i8, i1} @test_usub2(i8 %V) {
; CHECK-LABEL: @test_usub2(
-; CHECK-NEXT: ret { i8, i1 } undef
+; CHECK-NEXT: ret { i8, i1 } { i8 undef, i1 false }
;
%x = call {i8, i1} @llvm.usub.with.overflow.i8(i8 %V, i8 undef)
ret {i8, i1} %x
@@ -95,7 +95,7 @@ define {i8, i1} @test_usub2(i8 %V) {
define {i8, i1} @test_usub3(i8 %V) {
; CHECK-LABEL: @test_usub3(
-; CHECK-NEXT: ret { i8, i1 } undef
+; CHECK-NEXT: ret { i8, i1 } { i8 undef, i1 false }
;
%x = call {i8, i1} @llvm.usub.with.overflow.i8(i8 undef, i8 %V)
ret {i8, i1} %x
@@ -111,7 +111,7 @@ define {i8, i1} @test_ssub1(i8 %V) {
define {i8, i1} @test_ssub2(i8 %V) {
; CHECK-LABEL: @test_ssub2(
-; CHECK-NEXT: ret { i8, i1 } undef
+; CHECK-NEXT: ret { i8, i1 } { i8 undef, i1 false }
;
%x = call {i8, i1} @llvm.ssub.with.overflow.i8(i8 %V, i8 undef)
ret {i8, i1} %x
@@ -119,7 +119,7 @@ define {i8, i1} @test_ssub2(i8 %V) {
define {i8, i1} @test_ssub3(i8 %V) {
; CHECK-LABEL: @test_ssub3(
-; CHECK-NEXT: ret { i8, i1 } undef
+; CHECK-NEXT: ret { i8, i1 } { i8 undef, i1 false }
;
%x = call {i8, i1} @llvm.ssub.with.overflow.i8(i8 undef, i8 %V)
ret {i8, i1} %x
OpenPOWER on IntegriCloud