forked from OSchip/llvm-project
[InstSimplify] Simplify uadd/sadd/umul/smul with overflow intrinsics when the Zero or Undef is on the LHS.
Summary: This code was migrated from InstCombine a few years ago. InstCombine had nearby code that would move Constants to the RHS for these, but InstSimplify doesn't have such code on this path. Reviewers: spatel, majnemer, davide Reviewed By: spatel Subscribers: llvm-commits Differential Revision: https://reviews.llvm.org/D33473 llvm-svn: 303774
This commit is contained in:
parent
8205a1a9b6
commit
77e07cc010
|
@ -4440,19 +4440,21 @@ static Value *SimplifyIntrinsic(Function *F, IterTy ArgBegin, IterTy ArgEnd,
|
||||||
case Intrinsic::uadd_with_overflow:
|
case Intrinsic::uadd_with_overflow:
|
||||||
case Intrinsic::sadd_with_overflow: {
|
case Intrinsic::sadd_with_overflow: {
|
||||||
// X + undef -> undef
|
// X + undef -> undef
|
||||||
if (isa<UndefValue>(RHS))
|
if (isa<UndefValue>(LHS) || isa<UndefValue>(RHS))
|
||||||
return UndefValue::get(ReturnType);
|
return UndefValue::get(ReturnType);
|
||||||
|
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
case Intrinsic::umul_with_overflow:
|
case Intrinsic::umul_with_overflow:
|
||||||
case Intrinsic::smul_with_overflow: {
|
case Intrinsic::smul_with_overflow: {
|
||||||
|
// 0 * X -> { 0, false }
|
||||||
// X * 0 -> { 0, false }
|
// X * 0 -> { 0, false }
|
||||||
if (match(RHS, m_Zero()))
|
if (match(LHS, m_Zero()) || match(RHS, m_Zero()))
|
||||||
return Constant::getNullValue(ReturnType);
|
return Constant::getNullValue(ReturnType);
|
||||||
|
|
||||||
|
// undef * X -> { 0, false }
|
||||||
// X * undef -> { 0, false }
|
// X * undef -> { 0, false }
|
||||||
if (match(RHS, m_Undef()))
|
if (match(LHS, m_Undef()) || match(RHS, m_Undef()))
|
||||||
return Constant::getNullValue(ReturnType);
|
return Constant::getNullValue(ReturnType);
|
||||||
|
|
||||||
return nullptr;
|
return nullptr;
|
||||||
|
|
|
@ -35,6 +35,14 @@ define {i8, i1} @test_uadd3(i8 %v) {
|
||||||
ret {i8, i1} %result
|
ret {i8, i1} %result
|
||||||
}
|
}
|
||||||
|
|
||||||
|
define {i8, i1} @test_uadd4(i8 %v) {
|
||||||
|
; CHECK-LABEL: @test_uadd4(
|
||||||
|
; CHECK-NEXT: ret { i8, i1 } undef
|
||||||
|
;
|
||||||
|
%result = call {i8, i1} @llvm.uadd.with.overflow.i8(i8 undef, i8 %v)
|
||||||
|
ret {i8, i1} %result
|
||||||
|
}
|
||||||
|
|
||||||
define i1 @test_sadd1() {
|
define i1 @test_sadd1() {
|
||||||
; CHECK-LABEL: @test_sadd1(
|
; CHECK-LABEL: @test_sadd1(
|
||||||
; CHECK-NEXT: ret i1 true
|
; CHECK-NEXT: ret i1 true
|
||||||
|
@ -61,6 +69,14 @@ define {i8, i1} @test_sadd3(i8 %v) {
|
||||||
ret {i8, i1} %result
|
ret {i8, i1} %result
|
||||||
}
|
}
|
||||||
|
|
||||||
|
define {i8, i1} @test_sadd4(i8 %v) {
|
||||||
|
; CHECK-LABEL: @test_sadd4(
|
||||||
|
; CHECK-NEXT: ret { i8, i1 } undef
|
||||||
|
;
|
||||||
|
%result = call {i8, i1} @llvm.sadd.with.overflow.i8(i8 undef, i8 %v)
|
||||||
|
ret {i8, i1} %result
|
||||||
|
}
|
||||||
|
|
||||||
define {i8, i1} @test_usub1(i8 %V) {
|
define {i8, i1} @test_usub1(i8 %V) {
|
||||||
; CHECK-LABEL: @test_usub1(
|
; CHECK-LABEL: @test_usub1(
|
||||||
; CHECK-NEXT: ret { i8, i1 } zeroinitializer
|
; CHECK-NEXT: ret { i8, i1 } zeroinitializer
|
||||||
|
@ -125,6 +141,22 @@ define {i8, i1} @test_umul2(i8 %V) {
|
||||||
ret {i8, i1} %x
|
ret {i8, i1} %x
|
||||||
}
|
}
|
||||||
|
|
||||||
|
define {i8, i1} @test_umul3(i8 %V) {
|
||||||
|
; CHECK-LABEL: @test_umul3(
|
||||||
|
; CHECK-NEXT: ret { i8, i1 } zeroinitializer
|
||||||
|
;
|
||||||
|
%x = call {i8, i1} @llvm.umul.with.overflow.i8(i8 0, i8 %V)
|
||||||
|
ret {i8, i1} %x
|
||||||
|
}
|
||||||
|
|
||||||
|
define {i8, i1} @test_umul4(i8 %V) {
|
||||||
|
; CHECK-LABEL: @test_umul4(
|
||||||
|
; CHECK-NEXT: ret { i8, i1 } zeroinitializer
|
||||||
|
;
|
||||||
|
%x = call {i8, i1} @llvm.umul.with.overflow.i8(i8 undef, i8 %V)
|
||||||
|
ret {i8, i1} %x
|
||||||
|
}
|
||||||
|
|
||||||
define {i8, i1} @test_smul1(i8 %V) {
|
define {i8, i1} @test_smul1(i8 %V) {
|
||||||
; CHECK-LABEL: @test_smul1(
|
; CHECK-LABEL: @test_smul1(
|
||||||
; CHECK-NEXT: ret { i8, i1 } zeroinitializer
|
; CHECK-NEXT: ret { i8, i1 } zeroinitializer
|
||||||
|
@ -141,6 +173,22 @@ define {i8, i1} @test_smul2(i8 %V) {
|
||||||
ret {i8, i1} %x
|
ret {i8, i1} %x
|
||||||
}
|
}
|
||||||
|
|
||||||
|
define {i8, i1} @test_smul3(i8 %V) {
|
||||||
|
; CHECK-LABEL: @test_smul3(
|
||||||
|
; CHECK-NEXT: ret { i8, i1 } zeroinitializer
|
||||||
|
;
|
||||||
|
%x = call {i8, i1} @llvm.smul.with.overflow.i8(i8 0, i8 %V)
|
||||||
|
ret {i8, i1} %x
|
||||||
|
}
|
||||||
|
|
||||||
|
define {i8, i1} @test_smul4(i8 %V) {
|
||||||
|
; CHECK-LABEL: @test_smul4(
|
||||||
|
; CHECK-NEXT: ret { i8, i1 } zeroinitializer
|
||||||
|
;
|
||||||
|
%x = call {i8, i1} @llvm.smul.with.overflow.i8(i8 undef, i8 %V)
|
||||||
|
ret {i8, i1} %x
|
||||||
|
}
|
||||||
|
|
||||||
declare i256 @llvm.cttz.i256(i256 %src, i1 %is_zero_undef)
|
declare i256 @llvm.cttz.i256(i256 %src, i1 %is_zero_undef)
|
||||||
|
|
||||||
define i256 @test_cttz() {
|
define i256 @test_cttz() {
|
||||||
|
|
Loading…
Reference in New Issue