mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2025-01-18 13:34:04 +00:00
InstCombine: Strength reduce sadd.with.overflow into a regular nsw add if we can prove that it cannot overflow.
PR20194 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@212331 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
parent
a39d3ab819
commit
9c1df9164c
@ -421,6 +421,21 @@ Instruction *InstCombiner::visitCallInst(CallInst &CI) {
|
|||||||
return InsertValueInst::Create(Struct, II->getArgOperand(0), 0);
|
return InsertValueInst::Create(Struct, II->getArgOperand(0), 0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// We can strength reduce reduce this signed add into a regular add if we
|
||||||
|
// can prove that it will never overflow.
|
||||||
|
if (II->getIntrinsicID() == Intrinsic::sadd_with_overflow) {
|
||||||
|
Value *LHS = II->getArgOperand(0), *RHS = II->getArgOperand(1);
|
||||||
|
if (WillNotOverflowSignedAdd(LHS, RHS)) {
|
||||||
|
Value *Add = Builder->CreateNSWAdd(LHS, RHS);
|
||||||
|
Add->takeName(&CI);
|
||||||
|
Constant *V[] = {UndefValue::get(Add->getType()), Builder->getFalse()};
|
||||||
|
StructType *ST = cast<StructType>(II->getType());
|
||||||
|
Constant *Struct = ConstantStruct::get(ST, V);
|
||||||
|
return InsertValueInst::Create(Struct, Add, 0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
break;
|
break;
|
||||||
case Intrinsic::usub_with_overflow:
|
case Intrinsic::usub_with_overflow:
|
||||||
case Intrinsic::ssub_with_overflow:
|
case Intrinsic::ssub_with_overflow:
|
||||||
|
@ -3,6 +3,7 @@
|
|||||||
%overflow.result = type {i8, i1}
|
%overflow.result = type {i8, i1}
|
||||||
|
|
||||||
declare %overflow.result @llvm.uadd.with.overflow.i8(i8, i8)
|
declare %overflow.result @llvm.uadd.with.overflow.i8(i8, i8)
|
||||||
|
declare { i32, i1 } @llvm.sadd.with.overflow.i32(i32, i32)
|
||||||
declare %overflow.result @llvm.umul.with.overflow.i8(i8, i8)
|
declare %overflow.result @llvm.umul.with.overflow.i8(i8, i8)
|
||||||
declare double @llvm.powi.f64(double, i32) nounwind readonly
|
declare double @llvm.powi.f64(double, i32) nounwind readonly
|
||||||
declare i32 @llvm.cttz.i32(i32, i1) nounwind readnone
|
declare i32 @llvm.cttz.i32(i32, i1) nounwind readnone
|
||||||
@ -89,6 +90,18 @@ define i8 @uaddtest7(i8 %A, i8 %B) {
|
|||||||
; CHECK-NEXT: ret i8 %z
|
; CHECK-NEXT: ret i8 %z
|
||||||
}
|
}
|
||||||
|
|
||||||
|
; PR20194
|
||||||
|
define { i32, i1 } @saddtest1(i8 %a, i8 %b) {
|
||||||
|
%A = sext i8 %a to i32
|
||||||
|
%B = sext i8 %b to i32
|
||||||
|
%x = call { i32, i1 } @llvm.sadd.with.overflow.i32(i32 %A, i32 %B)
|
||||||
|
ret { i32, i1 } %x
|
||||||
|
; CHECK-LABEL: @saddtest1
|
||||||
|
; CHECK: %x = add nsw i32 %A, %B
|
||||||
|
; CHECK-NEXT: %1 = insertvalue { i32, i1 } { i32 undef, i1 false }, i32 %x, 0
|
||||||
|
; CHECK-NEXT: ret { i32, i1 } %1
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
define i8 @umultest1(i8 %A, i1* %overflowPtr) {
|
define i8 @umultest1(i8 %A, i1* %overflowPtr) {
|
||||||
%x = call %overflow.result @llvm.umul.with.overflow.i8(i8 0, i8 %A)
|
%x = call %overflow.result @llvm.umul.with.overflow.i8(i8 0, i8 %A)
|
||||||
|
Loading…
x
Reference in New Issue
Block a user