Skip to content

Commit add8cee

Browse files
committed
[InstCombine] canonicalize operands of fcmp ord/uno if they are known NaN
1 parent 61acc5d commit add8cee

File tree

3 files changed

+23
-11
lines changed

3 files changed

+23
-11
lines changed

llvm/include/llvm/Analysis/ValueTracking.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -276,6 +276,8 @@ struct KnownFPClass {
276276
return (KnownFPClasses & Mask) == fcNone;
277277
}
278278

279+
bool isKnownAlways(FPClassTest Mask) const { return isKnownNever(~Mask); }
280+
279281
bool isUnknown() const {
280282
return KnownFPClasses == fcAllFlags && !SignBit;
281283
}
@@ -285,6 +287,9 @@ struct KnownFPClass {
285287
return isKnownNever(fcNan);
286288
}
287289

290+
/// Return true if it's known this must always be a nan.
291+
bool isKnownAlwaysNaN() const { return isKnownAlways(fcNan); }
292+
288293
/// Return true if it's known this can never be an infinity.
289294
bool isKnownNeverInfinity() const {
290295
return isKnownNever(fcInf);

llvm/lib/Transforms/InstCombine/InstCombineCompares.cpp

Lines changed: 16 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -8103,13 +8103,22 @@ Instruction *InstCombinerImpl::visitFCmpInst(FCmpInst &I) {
81038103
// If we're just checking for a NaN (ORD/UNO) and have a non-NaN operand,
81048104
// then canonicalize the operand to 0.0.
81058105
if (Pred == CmpInst::FCMP_ORD || Pred == CmpInst::FCMP_UNO) {
8106-
if (!match(Op0, m_PosZeroFP()) &&
8107-
isKnownNeverNaN(Op0, 0, getSimplifyQuery().getWithInstruction(&I)))
8108-
return replaceOperand(I, 0, ConstantFP::getZero(OpType));
8109-
8110-
if (!match(Op1, m_PosZeroFP()) &&
8111-
isKnownNeverNaN(Op1, 0, getSimplifyQuery().getWithInstruction(&I)))
8112-
return replaceOperand(I, 1, ConstantFP::getZero(OpType));
8106+
if (!match(Op0, m_PosZeroFP())) {
8107+
KnownFPClass Known0 = computeKnownFPClass(Op0, fcAllFlags, &I);
8108+
if (Known0.isKnownNeverNaN())
8109+
return replaceOperand(I, 0, ConstantFP::getZero(OpType));
8110+
if (Known0.isKnownAlwaysNaN())
8111+
return replaceInstUsesWith(I,
8112+
Builder.getInt1(Pred == CmpInst::FCMP_UNO));
8113+
}
8114+
if (!match(Op1, m_PosZeroFP())) {
8115+
KnownFPClass Known1 = computeKnownFPClass(Op1, fcAllFlags, &I);
8116+
if (Known1.isKnownNeverNaN())
8117+
return replaceOperand(I, 1, ConstantFP::getZero(OpType));
8118+
if (Known1.isKnownAlwaysNaN())
8119+
return replaceInstUsesWith(I,
8120+
Builder.getInt1(Pred == CmpInst::FCMP_UNO));
8121+
}
81138122
}
81148123

81158124
// fcmp pred (fneg X), (fneg Y) -> fcmp swap(pred) X, Y

llvm/test/Transforms/InstCombine/fcmp-special.ll

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -188,17 +188,15 @@ define i1 @nnan_ops_to_fcmp_uno(float %x, float %y) {
188188

189189
define i1 @nan_ops_to_fcmp_ord(float nofpclass(inf zero sub norm) %x, float nofpclass(inf zero sub norm) %y) {
190190
; CHECK-LABEL: @nan_ops_to_fcmp_ord(
191-
; CHECK-NEXT: [[CMP:%.*]] = fcmp ord float [[X:%.*]], [[Y:%.*]]
192-
; CHECK-NEXT: ret i1 [[CMP]]
191+
; CHECK-NEXT: ret i1 false
193192
;
194193
%cmp = fcmp ord float %x, %y
195194
ret i1 %cmp
196195
}
197196

198197
define i1 @nan_ops_to_fcmp_uno(float nofpclass(inf zero sub norm) %x, float nofpclass(inf zero sub norm) %y) {
199198
; CHECK-LABEL: @nan_ops_to_fcmp_uno(
200-
; CHECK-NEXT: [[CMP:%.*]] = fcmp uno float [[X:%.*]], [[Y:%.*]]
201-
; CHECK-NEXT: ret i1 [[CMP]]
199+
; CHECK-NEXT: ret i1 true
202200
;
203201
%cmp = fcmp uno float %x, %y
204202
ret i1 %cmp

0 commit comments

Comments
 (0)