1
0
mirror of https://github.com/RPCS3/llvm-mirror.git synced 2024-10-19 02:52:53 +02:00

[ConstantFolding] fold abs intrinsic

The handling for minimum value is similar to cttz/ctlz with 0 just above this case.

Differential Revision: https://reviews.llvm.org/D84942
This commit is contained in:
Sanjay Patel 2020-07-31 11:50:39 -04:00
parent 30c3d4b6b4
commit 65a64fcb5b
2 changed files with 18 additions and 10 deletions

View File

@ -1436,6 +1436,7 @@ bool llvm::canConstantFoldCallTo(const CallBase *Call, const Function *F) {
case Intrinsic::launder_invariant_group:
case Intrinsic::strip_invariant_group:
case Intrinsic::masked_load:
case Intrinsic::abs:
case Intrinsic::smax:
case Intrinsic::smin:
case Intrinsic::umax:
@ -2505,6 +2506,18 @@ static Constant *ConstantFoldScalarCall2(StringRef Name,
return ConstantInt::get(Ty, C0->countTrailingZeros());
else
return ConstantInt::get(Ty, C0->countLeadingZeros());
case Intrinsic::abs:
// Undef or minimum val operand with poison min --> undef
assert(C1 && "Must be constant int");
if (C1->isOneValue() && (!C0 || C0->isMinSignedValue()))
return UndefValue::get(Ty);
// Undef operand with no poison min --> 0 (sign bit must be clear)
if (C1->isNullValue() && !C0)
return Constant::getNullValue(Ty);
return ConstantInt::get(Ty, C0->abs());
}
return nullptr;

View File

@ -6,8 +6,7 @@ declare <8 x i8> @llvm.abs.v8i8(<8 x i8>, i1)
define i8 @undef_val_min_poison() {
; CHECK-LABEL: @undef_val_min_poison(
; CHECK-NEXT: [[R:%.*]] = call i8 @llvm.abs.i8(i8 undef, i1 true)
; CHECK-NEXT: ret i8 [[R]]
; CHECK-NEXT: ret i8 undef
;
%r = call i8 @llvm.abs.i8(i8 undef, i1 true)
ret i8 %r
@ -15,8 +14,7 @@ define i8 @undef_val_min_poison() {
define i8 @undef_val_min_not_poison() {
; CHECK-LABEL: @undef_val_min_not_poison(
; CHECK-NEXT: [[R:%.*]] = call i8 @llvm.abs.i8(i8 undef, i1 false)
; CHECK-NEXT: ret i8 [[R]]
; CHECK-NEXT: ret i8 0
;
%r = call i8 @llvm.abs.i8(i8 undef, i1 false)
ret i8 %r
@ -24,8 +22,7 @@ define i8 @undef_val_min_not_poison() {
define i8 @min_val_min_poison() {
; CHECK-LABEL: @min_val_min_poison(
; CHECK-NEXT: [[R:%.*]] = call i8 @llvm.abs.i8(i8 -128, i1 true)
; CHECK-NEXT: ret i8 [[R]]
; CHECK-NEXT: ret i8 undef
;
%r = call i8 @llvm.abs.i8(i8 -128, i1 true)
ret i8 %r
@ -33,8 +30,7 @@ define i8 @min_val_min_poison() {
define i8 @min_val_min_not_poison() {
; CHECK-LABEL: @min_val_min_not_poison(
; CHECK-NEXT: [[R:%.*]] = call i8 @llvm.abs.i8(i8 -128, i1 false)
; CHECK-NEXT: ret i8 [[R]]
; CHECK-NEXT: ret i8 -128
;
%r = call i8 @llvm.abs.i8(i8 -128, i1 false)
ret i8 %r
@ -42,8 +38,7 @@ define i8 @min_val_min_not_poison() {
define <8 x i8> @vec_const() {
; CHECK-LABEL: @vec_const(
; CHECK-NEXT: [[R:%.*]] = call <8 x i8> @llvm.abs.v8i8(<8 x i8> <i8 -127, i8 -126, i8 -42, i8 -1, i8 0, i8 1, i8 42, i8 127>, i1 true)
; CHECK-NEXT: ret <8 x i8> [[R]]
; CHECK-NEXT: ret <8 x i8> <i8 127, i8 126, i8 42, i8 1, i8 0, i8 1, i8 42, i8 127>
;
%r = call <8 x i8> @llvm.abs.v8i8(<8 x i8> <i8 -127, i8 -126, i8 -42, i8 -1, i8 0, i8 1, i8 42, i8 127>, i1 1)
ret <8 x i8> %r