[llvm] 9397bdc - [InstCombine] fold fcmp with lossy casted constant
Sanjay Patel via llvm-commits
llvm-commits at lists.llvm.org
Tue Mar 8 09:41:21 PST 2022
Author: Sanjay Patel
Date: 2022-03-08T12:41:12-05:00
New Revision: 9397bdc67eb2b9eedc247a89bef01c2484b48b89
URL: https://github.com/llvm/llvm-project/commit/9397bdc67eb2b9eedc247a89bef01c2484b48b89
DIFF: https://github.com/llvm/llvm-project/commit/9397bdc67eb2b9eedc247a89bef01c2484b48b89.diff
LOG: [InstCombine] fold fcmp with lossy casted constant
This is noted as a missing clang warning in #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.
Added:
Modified:
llvm/lib/Transforms/InstCombine/InstCombineCompares.cpp
llvm/test/Transforms/InstCombine/fcmp.ll
Removed:
################################################################################
diff --git a/llvm/lib/Transforms/InstCombine/InstCombineCompares.cpp b/llvm/lib/Transforms/InstCombine/InstCombineCompares.cpp
index 273da7395f828..7d4e9b551c03c 100644
--- a/llvm/lib/Transforms/InstCombine/InstCombineCompares.cpp
+++ b/llvm/lib/Transforms/InstCombine/InstCombineCompares.cpp
@@ -6652,7 +6652,6 @@ Instruction *InstCombinerImpl::visitFCmpInst(FCmpInst &I) {
if (match(Op1, m_FPExt(m_Value(Y))) && X->getType() == Y->getType())
return new FCmpInst(Pred, X, Y, "", &I);
- // fcmp (fpext X), C -> fcmp X, (fptrunc C) if fptrunc is lossless
const APFloat *C;
if (match(Op1, m_APFloat(C))) {
const fltSemantics &FPSem =
@@ -6661,6 +6660,31 @@ Instruction *InstCombinerImpl::visitFCmpInst(FCmpInst &I) {
APFloat TruncC = *C;
TruncC.convert(FPSem, APFloat::rmNearestTiesToEven, &Lossy);
+ if (Lossy) {
+ // X can't possibly equal the higher-precision constant, so reduce any
+ // equality comparison.
+ // TODO: Other predicates can be handled via getFCmpCode().
+ switch (Pred) {
+ case FCmpInst::FCMP_OEQ:
+ // X is ordered and equal to an impossible constant --> false
+ return replaceInstUsesWith(I, ConstantInt::getFalse(I.getType()));
+ case FCmpInst::FCMP_ONE:
+ // X is ordered and not equal to an impossible constant --> ordered
+ return new FCmpInst(FCmpInst::FCMP_ORD, X,
+ ConstantFP::getNullValue(X->getType()));
+ case FCmpInst::FCMP_UEQ:
+ // X is unordered or equal to an impossible constant --> unordered
+ return new FCmpInst(FCmpInst::FCMP_UNO, X,
+ ConstantFP::getNullValue(X->getType()));
+ case FCmpInst::FCMP_UNE:
+ // X is unordered or not equal to an impossible constant --> true
+ return replaceInstUsesWith(I, ConstantInt::getTrue(I.getType()));
+ default:
+ break;
+ }
+ }
+
+ // fcmp (fpext X), C -> fcmp X, (fptrunc C) if fptrunc is lossless
// Avoid lossy conversions and denormals.
// Zero is a special case that's OK to convert.
APFloat Fabs = TruncC;
diff --git a/llvm/test/Transforms/InstCombine/fcmp.ll b/llvm/test/Transforms/InstCombine/fcmp.ll
index de8328c35ec02..fb6309262de59 100644
--- a/llvm/test/Transforms/InstCombine/fcmp.ll
+++ b/llvm/test/Transforms/InstCombine/fcmp.ll
@@ -674,9 +674,7 @@ define i1 @is_signbit_set_simplify_nan(double %x) {
define <2 x i1> @lossy_oeq(<2 x float> %x) {
; CHECK-LABEL: @lossy_oeq(
-; CHECK-NEXT: [[E:%.*]] = fpext <2 x float> [[X:%.*]] to <2 x double>
-; CHECK-NEXT: [[R:%.*]] = fcmp oeq <2 x double> [[E]], <double 1.000000e-01, double 1.000000e-01>
-; CHECK-NEXT: ret <2 x i1> [[R]]
+; CHECK-NEXT: ret <2 x i1> zeroinitializer
;
%e = fpext <2 x float> %x to <2 x double>
%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) {
; CHECK-LABEL: @lossy_one(
; CHECK-NEXT: [[E:%.*]] = fpext float [[X:%.*]] to double
; CHECK-NEXT: store double [[E]], double* [[P:%.*]], align 8
-; CHECK-NEXT: [[R:%.*]] = fcmp one double [[E]], 1.000000e-01
+; CHECK-NEXT: [[R:%.*]] = fcmp ord float [[X]], 0.000000e+00
; CHECK-NEXT: ret i1 [[R]]
;
%e = fpext float %x to double
@@ -698,8 +696,7 @@ define i1 @lossy_one(float %x, double* %p) {
define i1 @lossy_ueq(half %x) {
; CHECK-LABEL: @lossy_ueq(
-; CHECK-NEXT: [[E:%.*]] = fpext half [[X:%.*]] to double
-; CHECK-NEXT: [[R:%.*]] = fcmp ueq double [[E]], 6.553600e+04
+; CHECK-NEXT: [[R:%.*]] = fcmp uno half [[X:%.*]], 0xH0000
; CHECK-NEXT: ret i1 [[R]]
;
%e = fpext half %x to double
@@ -709,9 +706,7 @@ define i1 @lossy_ueq(half %x) {
define i1 @lossy_une(half %x) {
; CHECK-LABEL: @lossy_une(
-; CHECK-NEXT: [[E:%.*]] = fpext half [[X:%.*]] to float
-; CHECK-NEXT: [[R:%.*]] = fcmp une float [[E]], 2.049000e+03
-; CHECK-NEXT: ret i1 [[R]]
+; CHECK-NEXT: ret i1 true
;
%e = fpext half %x to float
%r = fcmp une float %e, 2049.0
More information about the llvm-commits
mailing list