[llvm] 7c135e1 - [InstSimplify] Treat float binop with identity as refining (#120098)
via llvm-commits
llvm-commits at lists.llvm.org
Tue Dec 17 01:58:55 PST 2024
Author: Nikita Popov
Date: 2024-12-17T10:58:52+01:00
New Revision: 7c135e17fbb7178466eafce9826c896518907637
URL: https://github.com/llvm/llvm-project/commit/7c135e17fbb7178466eafce9826c896518907637
DIFF: https://github.com/llvm/llvm-project/commit/7c135e17fbb7178466eafce9826c896518907637.diff
LOG: [InstSimplify] Treat float binop with identity as refining (#120098)
If x is NaN, then fmul (x, 1) may produce a different NaN value.
Our float semantics explicitly permit folding fmul (x, 1) to x, but we
can't do this when we're replacing a select input, as selects are
supposed to preserve the exact bitwise value.
Fixes
https://github.com/llvm/llvm-project/pull/115152#issuecomment-2545773114.
Added:
Modified:
llvm/lib/Analysis/InstructionSimplify.cpp
llvm/test/Transforms/InstSimplify/select-equivalence-fp.ll
Removed:
################################################################################
diff --git a/llvm/lib/Analysis/InstructionSimplify.cpp b/llvm/lib/Analysis/InstructionSimplify.cpp
index 3325cd972cf1eb..726c0f29e39928 100644
--- a/llvm/lib/Analysis/InstructionSimplify.cpp
+++ b/llvm/lib/Analysis/InstructionSimplify.cpp
@@ -4345,11 +4345,14 @@ static Value *simplifyWithOpReplaced(Value *V, Value *Op, Value *RepOp,
if (auto *BO = dyn_cast<BinaryOperator>(I)) {
unsigned Opcode = BO->getOpcode();
// id op x -> x, x op id -> x
- if (NewOps[0] == ConstantExpr::getBinOpIdentity(Opcode, I->getType()))
- return NewOps[1];
- if (NewOps[1] == ConstantExpr::getBinOpIdentity(Opcode, I->getType(),
- /* RHS */ true))
- return NewOps[0];
+ // Exclude floats, because x op id may produce a
diff erent NaN value.
+ if (!BO->getType()->isFPOrFPVectorTy()) {
+ if (NewOps[0] == ConstantExpr::getBinOpIdentity(Opcode, I->getType()))
+ return NewOps[1];
+ if (NewOps[1] == ConstantExpr::getBinOpIdentity(Opcode, I->getType(),
+ /* RHS */ true))
+ return NewOps[0];
+ }
// x & x -> x, x | x -> x
if ((Opcode == Instruction::And || Opcode == Instruction::Or) &&
diff --git a/llvm/test/Transforms/InstSimplify/select-equivalence-fp.ll b/llvm/test/Transforms/InstSimplify/select-equivalence-fp.ll
index 8af751d0a4246d..81132029466f90 100644
--- a/llvm/test/Transforms/InstSimplify/select-equivalence-fp.ll
+++ b/llvm/test/Transforms/InstSimplify/select-equivalence-fp.ll
@@ -114,10 +114,14 @@ define <2 x float> @select_fcmp_fadd_vec(<2 x float> %x) {
}
+; Should not fold, because the fmul by identity may produce a
diff erent NaN
+; value.
define float @select_fcmp_fmul_nonrefinement(float %x, float %y) {
; CHECK-LABEL: @select_fcmp_fmul_nonrefinement(
-; CHECK-NEXT: [[FMUL:%.*]] = fmul float [[Y:%.*]], [[X:%.*]]
-; CHECK-NEXT: ret float [[FMUL]]
+; CHECK-NEXT: [[FCMP:%.*]] = fcmp oeq float [[X:%.*]], 1.000000e+00
+; CHECK-NEXT: [[FMUL:%.*]] = fmul float [[Y:%.*]], [[X]]
+; CHECK-NEXT: [[SEL:%.*]] = select i1 [[FCMP]], float [[Y]], float [[FMUL]]
+; CHECK-NEXT: ret float [[SEL]]
;
%fcmp = fcmp oeq float %x, 1.0
%fmul = fmul float %y, %x
@@ -137,8 +141,10 @@ define float @select_fcmp_fmul(float %x) {
define float @select_fcmp_fdiv_nonrefinement(float %x, float %y) {
; CHECK-LABEL: @select_fcmp_fdiv_nonrefinement(
-; CHECK-NEXT: [[FDIV:%.*]] = fdiv float [[Y:%.*]], [[X:%.*]]
-; CHECK-NEXT: ret float [[FDIV]]
+; CHECK-NEXT: [[FCMP:%.*]] = fcmp oeq float [[X:%.*]], 1.000000e+00
+; CHECK-NEXT: [[FDIV:%.*]] = fdiv float [[Y:%.*]], [[X]]
+; CHECK-NEXT: [[SEL:%.*]] = select i1 [[FCMP]], float [[Y]], float [[FDIV]]
+; CHECK-NEXT: ret float [[SEL]]
;
%fcmp = fcmp oeq float %x, 1.0
%fdiv = fdiv float %y, %x
More information about the llvm-commits
mailing list