Skip to content

Commit 9397bdc

Browse files
committed
[InstCombine] fold fcmp with lossy casted constant
This is noted as a missing clang warning in llvm#54222 (and we should still make that enhancement). Alive2 proofs: https://alive2.llvm.org/ce/z/Q8drDq https://alive2.llvm.org/ce/z/pE6LRt I don't see a single conversion for all predicates using "getFCmpCode" logic, so other predicates are left as a TODO item.
1 parent f345f7e commit 9397bdc

File tree

2 files changed

+29
-10
lines changed

2 files changed

+29
-10
lines changed

llvm/lib/Transforms/InstCombine/InstCombineCompares.cpp

Lines changed: 25 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6652,7 +6652,6 @@ Instruction *InstCombinerImpl::visitFCmpInst(FCmpInst &I) {
66526652
if (match(Op1, m_FPExt(m_Value(Y))) && X->getType() == Y->getType())
66536653
return new FCmpInst(Pred, X, Y, "", &I);
66546654

6655-
// fcmp (fpext X), C -> fcmp X, (fptrunc C) if fptrunc is lossless
66566655
const APFloat *C;
66576656
if (match(Op1, m_APFloat(C))) {
66586657
const fltSemantics &FPSem =
@@ -6661,6 +6660,31 @@ Instruction *InstCombinerImpl::visitFCmpInst(FCmpInst &I) {
66616660
APFloat TruncC = *C;
66626661
TruncC.convert(FPSem, APFloat::rmNearestTiesToEven, &Lossy);
66636662

6663+
if (Lossy) {
6664+
// X can't possibly equal the higher-precision constant, so reduce any
6665+
// equality comparison.
6666+
// TODO: Other predicates can be handled via getFCmpCode().
6667+
switch (Pred) {
6668+
case FCmpInst::FCMP_OEQ:
6669+
// X is ordered and equal to an impossible constant --> false
6670+
return replaceInstUsesWith(I, ConstantInt::getFalse(I.getType()));
6671+
case FCmpInst::FCMP_ONE:
6672+
// X is ordered and not equal to an impossible constant --> ordered
6673+
return new FCmpInst(FCmpInst::FCMP_ORD, X,
6674+
ConstantFP::getNullValue(X->getType()));
6675+
case FCmpInst::FCMP_UEQ:
6676+
// X is unordered or equal to an impossible constant --> unordered
6677+
return new FCmpInst(FCmpInst::FCMP_UNO, X,
6678+
ConstantFP::getNullValue(X->getType()));
6679+
case FCmpInst::FCMP_UNE:
6680+
// X is unordered or not equal to an impossible constant --> true
6681+
return replaceInstUsesWith(I, ConstantInt::getTrue(I.getType()));
6682+
default:
6683+
break;
6684+
}
6685+
}
6686+
6687+
// fcmp (fpext X), C -> fcmp X, (fptrunc C) if fptrunc is lossless
66646688
// Avoid lossy conversions and denormals.
66656689
// Zero is a special case that's OK to convert.
66666690
APFloat Fabs = TruncC;

llvm/test/Transforms/InstCombine/fcmp.ll

Lines changed: 4 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -674,9 +674,7 @@ define i1 @is_signbit_set_simplify_nan(double %x) {
674674

675675
define <2 x i1> @lossy_oeq(<2 x float> %x) {
676676
; CHECK-LABEL: @lossy_oeq(
677-
; CHECK-NEXT: [[E:%.*]] = fpext <2 x float> [[X:%.*]] to <2 x double>
678-
; CHECK-NEXT: [[R:%.*]] = fcmp oeq <2 x double> [[E]], <double 1.000000e-01, double 1.000000e-01>
679-
; CHECK-NEXT: ret <2 x i1> [[R]]
677+
; CHECK-NEXT: ret <2 x i1> zeroinitializer
680678
;
681679
%e = fpext <2 x float> %x to <2 x double>
682680
%r = fcmp oeq <2 x double> %e, <double 0.1, double 0.1>
@@ -687,7 +685,7 @@ define i1 @lossy_one(float %x, double* %p) {
687685
; CHECK-LABEL: @lossy_one(
688686
; CHECK-NEXT: [[E:%.*]] = fpext float [[X:%.*]] to double
689687
; CHECK-NEXT: store double [[E]], double* [[P:%.*]], align 8
690-
; CHECK-NEXT: [[R:%.*]] = fcmp one double [[E]], 1.000000e-01
688+
; CHECK-NEXT: [[R:%.*]] = fcmp ord float [[X]], 0.000000e+00
691689
; CHECK-NEXT: ret i1 [[R]]
692690
;
693691
%e = fpext float %x to double
@@ -698,8 +696,7 @@ define i1 @lossy_one(float %x, double* %p) {
698696

699697
define i1 @lossy_ueq(half %x) {
700698
; CHECK-LABEL: @lossy_ueq(
701-
; CHECK-NEXT: [[E:%.*]] = fpext half [[X:%.*]] to double
702-
; CHECK-NEXT: [[R:%.*]] = fcmp ueq double [[E]], 6.553600e+04
699+
; CHECK-NEXT: [[R:%.*]] = fcmp uno half [[X:%.*]], 0xH0000
703700
; CHECK-NEXT: ret i1 [[R]]
704701
;
705702
%e = fpext half %x to double
@@ -709,9 +706,7 @@ define i1 @lossy_ueq(half %x) {
709706

710707
define i1 @lossy_une(half %x) {
711708
; CHECK-LABEL: @lossy_une(
712-
; CHECK-NEXT: [[E:%.*]] = fpext half [[X:%.*]] to float
713-
; CHECK-NEXT: [[R:%.*]] = fcmp une float [[E]], 2.049000e+03
714-
; CHECK-NEXT: ret i1 [[R]]
709+
; CHECK-NEXT: ret i1 true
715710
;
716711
%e = fpext half %x to float
717712
%r = fcmp une float %e, 2049.0

0 commit comments

Comments
 (0)