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:
parent
30c3d4b6b4
commit
65a64fcb5b
@ -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;
|
||||
|
@ -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
|
||||
|
Loading…
Reference in New Issue
Block a user