[llvm] r327208 - [ConstantFold] fp_binop AnyConstant, undef --> NaN

Sanjay Patel via llvm-commits llvm-commits at lists.llvm.org
Sat Mar 10 07:56:25 PST 2018


Author: spatel
Date: Sat Mar 10 07:56:25 2018
New Revision: 327208

URL: http://llvm.org/viewvc/llvm-project?rev=327208&view=rev
Log:
[ConstantFold] fp_binop AnyConstant, undef --> NaN

With the updated LangRef ( D44216 / rL327138 ) in place, we can proceed with more constant folding.

I'm intentionally taking the conservative path here: no matter what the constant or the FMF, we can 
always fold to NaN. This is because the undef operand can be chosen as NaN, and in our simplified 
default FP env, nothing else happens - NaN just propagates to the result. If we find some way/need 
to propagate undef instead, that can be added subsequently.

The tests show that we always choose the same quiet NaN constant (0x7FF8000000000000 in IR text). 
There were suggestions to improve that with a 'NaN' string token or not always print a 64-bit hex 
value, but those are independent changes. We might also consider setting/propagating the payload of 
NaN constants as an enhancement.

Differential Revision: https://reviews.llvm.org/D44308

Modified:
    llvm/trunk/lib/IR/ConstantFold.cpp
    llvm/trunk/test/Transforms/InstCombine/fsub.ll
    llvm/trunk/test/Transforms/InstSimplify/fp-undef.ll

Modified: llvm/trunk/lib/IR/ConstantFold.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/IR/ConstantFold.cpp?rev=327208&r1=327207&r2=327208&view=diff
==============================================================================
--- llvm/trunk/lib/IR/ConstantFold.cpp (original)
+++ llvm/trunk/lib/IR/ConstantFold.cpp Sat Mar 10 07:56:25 2018
@@ -1012,8 +1012,14 @@ Constant *llvm::ConstantFoldBinaryInstru
       // [any flop] undef, undef -> undef
       if (isa<UndefValue>(C1) && isa<UndefValue>(C2))
         return C1;
-      // TODO: Handle one undef operand and some other constant.
-      return nullptr;
+      // [any flop] C, undef -> NaN
+      // [any flop] undef, C -> NaN
+      // We could potentially specialize NaN/Inf constants vs. 'normal'
+      // constants (possibly differently depending on opcode and operand). This
+      // would allow returning undef sometimes. But it is always safe to fold to
+      // NaN because we can choose the undef operand as NaN, and any FP opcode
+      // with a NaN operand will propagate NaN.
+      return ConstantFP::getNaN(C1->getType());
     case Instruction::BinaryOpsEnd:
       llvm_unreachable("Invalid BinaryOp");
     }

Modified: llvm/trunk/test/Transforms/InstCombine/fsub.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Transforms/InstCombine/fsub.ll?rev=327208&r1=327207&r2=327208&view=diff
==============================================================================
--- llvm/trunk/test/Transforms/InstCombine/fsub.ll (original)
+++ llvm/trunk/test/Transforms/InstCombine/fsub.ll Sat Mar 10 07:56:25 2018
@@ -47,31 +47,3 @@ define float @fsub_fast_undef(float %val
   ret float %sub
 }
 
-define float @fneg_undef(float %val) {
-; CHECK-LABEL: @fneg_undef(
-; CHECK-NEXT:    ret float fsub (float -0.000000e+00, float undef)
-;
-  %sub = fsub float -0.0, undef
-  ret float %sub
-}
-
-define float @fneg_fast_undef(float %val) {
-; CHECK-LABEL: @fneg_fast_undef(
-; CHECK-NEXT:    ret float fsub (float -0.000000e+00, float undef)
-;
-  %sub = fsub fast float -0.0, undef
-  ret float %sub
-}
-
-; This folds to a constant expression, which produced 0 instructions
-; contrary to the expected one for negation.
-
-define float @inconsistent_numbers_fsub_undef(float %val) {
-; CHECK-LABEL: @inconsistent_numbers_fsub_undef(
-; CHECK-NEXT:    ret float fsub (float -0.000000e+00, float undef)
-;
-  %sub0 = fsub fast float %val, undef
-  %sub1 = fsub fast float %sub0, %val
-  ret float %sub1
-}
-

Modified: llvm/trunk/test/Transforms/InstSimplify/fp-undef.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Transforms/InstSimplify/fp-undef.ll?rev=327208&r1=327207&r2=327208&view=diff
==============================================================================
--- llvm/trunk/test/Transforms/InstSimplify/fp-undef.ll (original)
+++ llvm/trunk/test/Transforms/InstSimplify/fp-undef.ll Sat Mar 10 07:56:25 2018
@@ -221,7 +221,7 @@ define double @frem_undef_undef(double %
 
 define float @fadd_undef_op0_nnan_constant(float %x) {
 ; CHECK-LABEL: @fadd_undef_op0_nnan_constant(
-; CHECK-NEXT:    ret float fadd (float undef, float 1.000000e+00)
+; CHECK-NEXT:    ret float 0x7FF8000000000000
 ;
   %r = fadd nnan float undef, 1.0
   ret float %r
@@ -229,7 +229,7 @@ define float @fadd_undef_op0_nnan_consta
 
 define float @fadd_undef_op1_constant(float %x) {
 ; CHECK-LABEL: @fadd_undef_op1_constant(
-; CHECK-NEXT:    ret float fadd (float 2.000000e+00, float undef)
+; CHECK-NEXT:    ret float 0x7FF8000000000000
 ;
   %r = fadd float 2.0, undef
   ret float %r
@@ -237,7 +237,7 @@ define float @fadd_undef_op1_constant(fl
 
 define float @fsub_undef_op0_fast_constant(float %x) {
 ; CHECK-LABEL: @fsub_undef_op0_fast_constant(
-; CHECK-NEXT:    ret float fsub (float undef, float 3.000000e+00)
+; CHECK-NEXT:    ret float 0x7FF8000000000000
 ;
   %r = fsub fast float undef, 3.0
   ret float %r
@@ -245,7 +245,7 @@ define float @fsub_undef_op0_fast_consta
 
 define float @fsub_undef_op1_constant(float %x) {
 ; CHECK-LABEL: @fsub_undef_op1_constant(
-; CHECK-NEXT:    ret float fsub (float 4.000000e+00, float undef)
+; CHECK-NEXT:    ret float 0x7FF8000000000000
 ;
   %r = fsub float 4.0, undef
   ret float %r
@@ -253,7 +253,7 @@ define float @fsub_undef_op1_constant(fl
 
 define float @fmul_undef_op0_nnan_constant(float %x) {
 ; CHECK-LABEL: @fmul_undef_op0_nnan_constant(
-; CHECK-NEXT:    ret float fmul (float undef, float 5.000000e+00)
+; CHECK-NEXT:    ret float 0x7FF8000000000000
 ;
   %r = fmul nnan float undef, 5.0
   ret float %r
@@ -261,7 +261,7 @@ define float @fmul_undef_op0_nnan_consta
 
 define float @fmul_undef_op1_constant(float %x) {
 ; CHECK-LABEL: @fmul_undef_op1_constant(
-; CHECK-NEXT:    ret float fmul (float 6.000000e+00, float undef)
+; CHECK-NEXT:    ret float 0x7FF8000000000000
 ;
   %r = fmul float 6.0, undef
   ret float %r
@@ -269,7 +269,7 @@ define float @fmul_undef_op1_constant(fl
 
 define float @fdiv_undef_op0_fast_constant(float %x) {
 ; CHECK-LABEL: @fdiv_undef_op0_fast_constant(
-; CHECK-NEXT:    ret float fdiv (float undef, float 7.000000e+00)
+; CHECK-NEXT:    ret float 0x7FF8000000000000
 ;
   %r = fdiv fast float undef, 7.0
   ret float %r
@@ -277,7 +277,7 @@ define float @fdiv_undef_op0_fast_consta
 
 define float @fdiv_undef_op1_constant(float %x) {
 ; CHECK-LABEL: @fdiv_undef_op1_constant(
-; CHECK-NEXT:    ret float fdiv (float 8.000000e+00, float undef)
+; CHECK-NEXT:    ret float 0x7FF8000000000000
 ;
   %r = fdiv float 8.0, undef
   ret float %r
@@ -285,7 +285,7 @@ define float @fdiv_undef_op1_constant(fl
 
 define float @frem_undef_op0_nnan_constant(float %x) {
 ; CHECK-LABEL: @frem_undef_op0_nnan_constant(
-; CHECK-NEXT:    ret float frem (float undef, float 9.000000e+00)
+; CHECK-NEXT:    ret float 0x7FF8000000000000
 ;
   %r = frem nnan float undef, 9.0
   ret float %r
@@ -293,7 +293,7 @@ define float @frem_undef_op0_nnan_consta
 
 define float @frem_undef_op1_constant(float %x) {
 ; CHECK-LABEL: @frem_undef_op1_constant(
-; CHECK-NEXT:    ret float frem (float 1.000000e+01, float undef)
+; CHECK-NEXT:    ret float 0x7FF8000000000000
 ;
   %r = frem float 10.0, undef
   ret float %r
@@ -303,7 +303,7 @@ define float @frem_undef_op1_constant(fl
 
 define double @fadd_undef_op0_constant_nan(double %x) {
 ; CHECK-LABEL: @fadd_undef_op0_constant_nan(
-; CHECK-NEXT:    ret double fadd (double undef, double 0x7FF8000000000000)
+; CHECK-NEXT:    ret double 0x7FF8000000000000
 ;
   %r = fadd double undef, 0x7FF8000000000000
   ret double %r
@@ -311,7 +311,7 @@ define double @fadd_undef_op0_constant_n
 
 define double @fadd_undef_op1_fast_constant_nan(double %x) {
 ; CHECK-LABEL: @fadd_undef_op1_fast_constant_nan(
-; CHECK-NEXT:    ret double fadd (double 0xFFF0000000000001, double undef)
+; CHECK-NEXT:    ret double 0x7FF8000000000000
 ;
   %r = fadd fast double 0xFFF0000000000001, undef
   ret double %r
@@ -319,7 +319,7 @@ define double @fadd_undef_op1_fast_const
 
 define double @fsub_undef_op0_constant_nan(double %x) {
 ; CHECK-LABEL: @fsub_undef_op0_constant_nan(
-; CHECK-NEXT:    ret double fsub (double undef, double 0xFFF8000000000010)
+; CHECK-NEXT:    ret double 0x7FF8000000000000
 ;
   %r = fsub double undef, 0xFFF8000000000010
   ret double %r
@@ -327,7 +327,7 @@ define double @fsub_undef_op0_constant_n
 
 define double @fsub_undef_op1_nnan_constant_nan(double %x) {
 ; CHECK-LABEL: @fsub_undef_op1_nnan_constant_nan(
-; CHECK-NEXT:    ret double fsub (double 0x7FF0000000000011, double undef)
+; CHECK-NEXT:    ret double 0x7FF8000000000000
 ;
   %r = fsub nnan double 0x7FF0000000000011, undef
   ret double %r
@@ -335,7 +335,7 @@ define double @fsub_undef_op1_nnan_const
 
 define double @fmul_undef_op0_constant_nan(double %x) {
 ; CHECK-LABEL: @fmul_undef_op0_constant_nan(
-; CHECK-NEXT:    ret double fmul (double undef, double 0x7FF8000000000100)
+; CHECK-NEXT:    ret double 0x7FF8000000000000
 ;
   %r = fmul double undef, 0x7FF8000000000100
   ret double %r
@@ -343,7 +343,7 @@ define double @fmul_undef_op0_constant_n
 
 define double @fmul_undef_op1_fast_constant_nan(double %x) {
 ; CHECK-LABEL: @fmul_undef_op1_fast_constant_nan(
-; CHECK-NEXT:    ret double fmul (double 0xFFF0000000000101, double undef)
+; CHECK-NEXT:    ret double 0x7FF8000000000000
 ;
   %r = fmul fast double 0xFFF0000000000101, undef
   ret double %r
@@ -351,7 +351,7 @@ define double @fmul_undef_op1_fast_const
 
 define double @fdiv_undef_op0_constant_nan(double %x) {
 ; CHECK-LABEL: @fdiv_undef_op0_constant_nan(
-; CHECK-NEXT:    ret double fdiv (double undef, double 0xFFF8000000000110)
+; CHECK-NEXT:    ret double 0x7FF8000000000000
 ;
   %r = fdiv double undef, 0xFFF8000000000110
   ret double %r
@@ -359,7 +359,7 @@ define double @fdiv_undef_op0_constant_n
 
 define double @fdiv_undef_op1_nnan_constant_nan(double %x) {
 ; CHECK-LABEL: @fdiv_undef_op1_nnan_constant_nan(
-; CHECK-NEXT:    ret double fdiv (double 0x7FF0000000000111, double undef)
+; CHECK-NEXT:    ret double 0x7FF8000000000000
 ;
   %r = fdiv nnan double 0x7FF0000000000111, undef
   ret double %r
@@ -367,7 +367,7 @@ define double @fdiv_undef_op1_nnan_const
 
 define double @frem_undef_op0_constant_nan(double %x) {
 ; CHECK-LABEL: @frem_undef_op0_constant_nan(
-; CHECK-NEXT:    ret double frem (double undef, double 0x7FF8000000001000)
+; CHECK-NEXT:    ret double 0x7FF8000000000000
 ;
   %r = frem double undef, 0x7FF8000000001000
   ret double %r
@@ -375,7 +375,7 @@ define double @frem_undef_op0_constant_n
 
 define double @frem_undef_op1_fast_constant_nan(double %x) {
 ; CHECK-LABEL: @frem_undef_op1_fast_constant_nan(
-; CHECK-NEXT:    ret double frem (double 0xFFF0000000001001, double undef)
+; CHECK-NEXT:    ret double 0x7FF8000000000000
 ;
   %r = frem fast double 0xFFF0000000001001, undef
   ret double %r
@@ -385,7 +385,7 @@ define double @frem_undef_op1_fast_const
 
 define double @fadd_undef_op0_constant_inf(double %x) {
 ; CHECK-LABEL: @fadd_undef_op0_constant_inf(
-; CHECK-NEXT:    ret double fadd (double undef, double 0x7FF0000000000000)
+; CHECK-NEXT:    ret double 0x7FF8000000000000
 ;
   %r = fadd double undef, 0x7FF0000000000000
   ret double %r
@@ -393,7 +393,7 @@ define double @fadd_undef_op0_constant_i
 
 define double @fadd_undef_op1_fast_constant_inf(double %x) {
 ; CHECK-LABEL: @fadd_undef_op1_fast_constant_inf(
-; CHECK-NEXT:    ret double fadd (double 0xFFF0000000000000, double undef)
+; CHECK-NEXT:    ret double 0x7FF8000000000000
 ;
   %r = fadd fast double 0xFFF0000000000000, undef
   ret double %r
@@ -401,7 +401,7 @@ define double @fadd_undef_op1_fast_const
 
 define double @fsub_undef_op0_constant_inf(double %x) {
 ; CHECK-LABEL: @fsub_undef_op0_constant_inf(
-; CHECK-NEXT:    ret double fsub (double undef, double 0xFFF0000000000000)
+; CHECK-NEXT:    ret double 0x7FF8000000000000
 ;
   %r = fsub double undef, 0xFFF0000000000000
   ret double %r
@@ -409,7 +409,7 @@ define double @fsub_undef_op0_constant_i
 
 define double @fsub_undef_op1_ninf_constant_inf(double %x) {
 ; CHECK-LABEL: @fsub_undef_op1_ninf_constant_inf(
-; CHECK-NEXT:    ret double fsub (double 0x7FF0000000000000, double undef)
+; CHECK-NEXT:    ret double 0x7FF8000000000000
 ;
   %r = fsub ninf double 0x7FF0000000000000, undef
   ret double %r
@@ -417,7 +417,7 @@ define double @fsub_undef_op1_ninf_const
 
 define double @fmul_undef_op0_constant_inf(double %x) {
 ; CHECK-LABEL: @fmul_undef_op0_constant_inf(
-; CHECK-NEXT:    ret double fmul (double undef, double 0x7FF0000000000000)
+; CHECK-NEXT:    ret double 0x7FF8000000000000
 ;
   %r = fmul double undef, 0x7FF0000000000000
   ret double %r
@@ -425,7 +425,7 @@ define double @fmul_undef_op0_constant_i
 
 define double @fmul_undef_op1_fast_constant_inf(double %x) {
 ; CHECK-LABEL: @fmul_undef_op1_fast_constant_inf(
-; CHECK-NEXT:    ret double fmul (double 0xFFF0000000000000, double undef)
+; CHECK-NEXT:    ret double 0x7FF8000000000000
 ;
   %r = fmul fast double 0xFFF0000000000000, undef
   ret double %r
@@ -433,7 +433,7 @@ define double @fmul_undef_op1_fast_const
 
 define double @fdiv_undef_op0_constant_inf(double %x) {
 ; CHECK-LABEL: @fdiv_undef_op0_constant_inf(
-; CHECK-NEXT:    ret double fdiv (double undef, double 0xFFF0000000000000)
+; CHECK-NEXT:    ret double 0x7FF8000000000000
 ;
   %r = fdiv double undef, 0xFFF0000000000000
   ret double %r
@@ -441,7 +441,7 @@ define double @fdiv_undef_op0_constant_i
 
 define double @fdiv_undef_op1_ninf_constant_inf(double %x) {
 ; CHECK-LABEL: @fdiv_undef_op1_ninf_constant_inf(
-; CHECK-NEXT:    ret double fdiv (double 0x7FF0000000000000, double undef)
+; CHECK-NEXT:    ret double 0x7FF8000000000000
 ;
   %r = fdiv ninf double 0x7FF0000000000000, undef
   ret double %r
@@ -449,7 +449,7 @@ define double @fdiv_undef_op1_ninf_const
 
 define double @frem_undef_op0_constant_inf(double %x) {
 ; CHECK-LABEL: @frem_undef_op0_constant_inf(
-; CHECK-NEXT:    ret double frem (double undef, double 0x7FF0000000000000)
+; CHECK-NEXT:    ret double 0x7FF8000000000000
 ;
   %r = frem double undef, 0x7FF0000000000000
   ret double %r
@@ -457,7 +457,7 @@ define double @frem_undef_op0_constant_i
 
 define double @frem_undef_op1_fast_constant_inf(double %x) {
 ; CHECK-LABEL: @frem_undef_op1_fast_constant_inf(
-; CHECK-NEXT:    ret double frem (double 0xFFF0000000000000, double undef)
+; CHECK-NEXT:    ret double 0x7FF8000000000000
 ;
   %r = frem fast double 0xFFF0000000000000, undef
   ret double %r




More information about the llvm-commits mailing list