Skip to content

Commit 1b0fd5e

Browse files
committed
[InstCombine] Handle more fp op/intrinsics
1 parent cb419c7 commit 1b0fd5e

File tree

2 files changed

+69
-29
lines changed

2 files changed

+69
-29
lines changed

llvm/lib/Transforms/InstCombine/InstCombineSelect.cpp

Lines changed: 58 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -2782,16 +2782,31 @@ static bool ignoreSignBitOfZero(Instruction &I) {
27822782
// Check if the sign bit is ignored by the only user.
27832783
if (!I.hasOneUse())
27842784
return false;
2785-
Instruction *User = I.user_back();
2786-
2787-
// fcmp treats both positive and negative zero as equal.
2788-
if (User->getOpcode() == Instruction::FCmp)
2785+
auto *FPOp = dyn_cast<FPMathOperator>(I.user_back());
2786+
if (!FPOp)
2787+
return false;
2788+
if (FPOp->hasNoSignedZeros())
27892789
return true;
27902790

2791-
if (auto *FPOp = dyn_cast<FPMathOperator>(User))
2792-
return FPOp->hasNoSignedZeros();
2793-
2794-
return false;
2791+
switch (FPOp->getOpcode()) {
2792+
case Instruction::FCmp:
2793+
// fcmp treats both positive and negative zero as equal.
2794+
return true;
2795+
case Instruction::Call:
2796+
if (auto *II = dyn_cast<IntrinsicInst>(FPOp)) {
2797+
switch (II->getIntrinsicID()) {
2798+
case Intrinsic::fabs:
2799+
return true;
2800+
case Intrinsic::copysign:
2801+
return II->getArgOperand(0) == &I;
2802+
default:
2803+
return false;
2804+
}
2805+
}
2806+
return false;
2807+
default:
2808+
return false;
2809+
}
27952810
}
27962811

27972812
/// Return true if the sign bit of result can be ignored when the result is NaN.
@@ -2802,16 +2817,43 @@ static bool ignoreSignBitOfNaN(Instruction &I) {
28022817
// Check if the sign bit is ignored by the only user.
28032818
if (!I.hasOneUse())
28042819
return false;
2805-
Instruction *User = I.user_back();
2806-
2807-
// fcmp ignores the sign bit of NaN.
2808-
if (User->getOpcode() == Instruction::FCmp)
2820+
auto *FPOp = dyn_cast<FPMathOperator>(I.user_back());
2821+
if (!FPOp)
2822+
return false;
2823+
if (FPOp->hasNoNaNs())
28092824
return true;
28102825

2811-
if (auto *FPOp = dyn_cast<FPMathOperator>(User))
2812-
return FPOp->hasNoNaNs();
2813-
2814-
return false;
2826+
switch (FPOp->getOpcode()) {
2827+
case Instruction::FNeg:
2828+
case Instruction::Select:
2829+
case Instruction::PHI:
2830+
return false;
2831+
case Instruction::Call: {
2832+
if (auto *II = dyn_cast<IntrinsicInst>(FPOp)) {
2833+
switch (II->getIntrinsicID()) {
2834+
case Intrinsic::fabs:
2835+
return true;
2836+
case Intrinsic::copysign:
2837+
return II->getArgOperand(0) == &I;
2838+
case Intrinsic::maxnum:
2839+
case Intrinsic::minnum:
2840+
case Intrinsic::maximum:
2841+
case Intrinsic::minimum:
2842+
case Intrinsic::maximumnum:
2843+
case Intrinsic::minimumnum:
2844+
case Intrinsic::canonicalize:
2845+
return false;
2846+
default:
2847+
// Other proper FP intrinsics ignore the sign bit of NaN.
2848+
return true;
2849+
}
2850+
}
2851+
return false;
2852+
}
2853+
default:
2854+
// Other proper FP math operations ignore the sign bit of NaN.
2855+
return true;
2856+
}
28152857
}
28162858

28172859
// Canonicalize select with fcmp to fabs(). -0.0 makes this tricky. We need

llvm/test/Transforms/InstCombine/fabs.ll

Lines changed: 11 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1329,35 +1329,33 @@ define float @test_fabs_fsub_used_by_fpop_nnan(float %x, float %y) {
13291329
ret float %add
13301330
}
13311331

1332-
; Negative tests
1333-
1334-
define float @test_fabs_used_by_fpop_nnan(float %x, float %y) {
1335-
; CHECK-LABEL: @test_fabs_used_by_fpop_nnan(
1336-
; CHECK-NEXT: [[CMP:%.*]] = fcmp oge float [[X:%.*]], 0.000000e+00
1337-
; CHECK-NEXT: [[NEG:%.*]] = fneg float [[X]]
1338-
; CHECK-NEXT: [[SEL:%.*]] = select i1 [[CMP]], float [[X]], float [[NEG]]
1339-
; CHECK-NEXT: [[ADD:%.*]] = fadd nnan float [[SEL]], [[Y:%.*]]
1332+
define float @test_fabs_used_by_fpop_nsz(float %x, float %y) {
1333+
; CHECK-LABEL: @test_fabs_used_by_fpop_nsz(
1334+
; CHECK-NEXT: [[SEL:%.*]] = call float @llvm.fabs.f32(float [[X:%.*]])
1335+
; CHECK-NEXT: [[ADD:%.*]] = fadd nsz float [[SEL]], [[Y:%.*]]
13401336
; CHECK-NEXT: ret float [[ADD]]
13411337
;
13421338
%cmp = fcmp oge float %x, 0.000000e+00
13431339
%neg = fneg float %x
13441340
%sel = select i1 %cmp, float %x, float %neg
1345-
%add = fadd nnan float %sel, %y
1341+
%add = fadd nsz float %sel, %y
13461342
ret float %add
13471343
}
13481344

1349-
define float @test_fabs_used_by_fpop_nsz(float %x, float %y) {
1350-
; CHECK-LABEL: @test_fabs_used_by_fpop_nsz(
1345+
; Negative tests
1346+
1347+
define float @test_fabs_used_by_fpop_nnan(float %x, float %y) {
1348+
; CHECK-LABEL: @test_fabs_used_by_fpop_nnan(
13511349
; CHECK-NEXT: [[CMP:%.*]] = fcmp oge float [[X:%.*]], 0.000000e+00
13521350
; CHECK-NEXT: [[NEG:%.*]] = fneg float [[X]]
13531351
; CHECK-NEXT: [[SEL:%.*]] = select i1 [[CMP]], float [[X]], float [[NEG]]
1354-
; CHECK-NEXT: [[ADD:%.*]] = fadd nsz float [[SEL]], [[Y:%.*]]
1352+
; CHECK-NEXT: [[ADD:%.*]] = fadd nnan float [[SEL]], [[Y:%.*]]
13551353
; CHECK-NEXT: ret float [[ADD]]
13561354
;
13571355
%cmp = fcmp oge float %x, 0.000000e+00
13581356
%neg = fneg float %x
13591357
%sel = select i1 %cmp, float %x, float %neg
1360-
%add = fadd nsz float %sel, %y
1358+
%add = fadd nnan float %sel, %y
13611359
ret float %add
13621360
}
13631361

0 commit comments

Comments
 (0)