[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