[PATCH] D116952: [ConstantFolding] Flush folded denormals to zero when using fastmath
David Candler via Phabricator via llvm-commits
llvm-commits at lists.llvm.org
Mon Jan 10 09:15:36 PST 2022
dcandler created this revision.
dcandler added reviewers: spatel, craig.topper.
Herald added a subscriber: hiraditya.
dcandler requested review of this revision.
Herald added a project: LLVM.
Herald added a subscriber: llvm-commits.
When using fast math, an instruction folded to a constant can produce
a denormal. This differs from the result of the original operation,
which would have flushed the denormal to zero. In order to have the
values match, this patch adds a check when the instruction is folded,
so that the constant returned is set to zero for fast instructions
when a denormal is detected.
Repository:
rG LLVM Github Monorepo
https://reviews.llvm.org/D116952
Files:
llvm/lib/Analysis/ConstantFolding.cpp
llvm/test/Transforms/InstCombine/constant-fold-denormals.ll
Index: llvm/test/Transforms/InstCombine/constant-fold-denormals.ll
===================================================================
--- /dev/null
+++ llvm/test/Transforms/InstCombine/constant-fold-denormals.ll
@@ -0,0 +1,29 @@
+; RUN: opt -S -instcombine < %s | FileCheck %s
+
+define float @test_float() {
+; CHECK-LABEL: @test_float(
+; CHECK-NEXT: ret float 0x3800000000000000
+ %mul = fmul float 0x3810000000000000, 5.000000e-01
+ ret float %mul
+}
+
+define double @test_double() {
+; CHECK-LABEL: @test_double(
+; CHECK-NEXT: ret double 0x8000000000000
+ %mul = fmul double 0x10000000000000, 5.000000e-01
+ ret double %mul
+}
+
+define float @test_float_fast() {
+; CHECK-LABEL: @test_float_fast(
+; CHECK-NEXT: ret float 0.000000e+00
+ %mul = fmul fast float 0x3810000000000000, 5.000000e-01
+ ret float %mul
+}
+
+define double @test_double_fast() {
+; CHECK-LABEL: @test_double_fast(
+; CHECK-NEXT: ret double 0.000000e+00
+ %mul = fmul fast double 0x10000000000000, 5.000000e-01
+ ret double %mul
+}
Index: llvm/lib/Analysis/ConstantFolding.cpp
===================================================================
--- llvm/lib/Analysis/ConstantFolding.cpp
+++ llvm/lib/Analysis/ConstantFolding.cpp
@@ -1001,8 +1001,32 @@
if (Instruction::isUnaryOp(Opcode))
return ConstantFoldUnaryOpOperand(Opcode, Ops[0], DL);
- if (Instruction::isBinaryOp(Opcode))
+ if (Instruction::isBinaryOp(Opcode)) {
+ switch (Opcode) {
+ case Instruction::FAdd:
+ case Instruction::FSub:
+ case Instruction::FMul:
+ case Instruction::FDiv:
+ case Instruction::FRem:
+ // If folding produces a denormal constant from a fast instruction,
+ // flush it to zero.
+ if (auto *I = dyn_cast<Instruction>(InstOrCE)) {
+ if (I->isFast()) {
+ Constant *C =
+ ConstantFoldBinaryOpOperands(Opcode, Ops[0], Ops[1], DL);
+ if (ConstantFP *CFP = dyn_cast<ConstantFP>(C)) {
+ if (CFP->getValueAPF().isDenormal()) {
+ return Constant::getNullValue(C->getType());
+ }
+ }
+ return C;
+ }
+ }
+ default:
+ break;
+ }
return ConstantFoldBinaryOpOperands(Opcode, Ops[0], Ops[1], DL);
+ }
if (Instruction::isCast(Opcode))
return ConstantFoldCastOperand(Opcode, Ops[0], DestTy, DL);
-------------- next part --------------
A non-text attachment was scrubbed...
Name: D116952.398664.patch
Type: text/x-patch
Size: 2343 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20220110/e493a1e2/attachment.bin>
More information about the llvm-commits
mailing list