[llvm] r328140 - [InstSimplify] fp_binop X, NaN --> NaN

Sanjay Patel via llvm-commits llvm-commits at lists.llvm.org
Wed Mar 21 12:31:53 PDT 2018


Author: spatel
Date: Wed Mar 21 12:31:53 2018
New Revision: 328140

URL: http://llvm.org/viewvc/llvm-project?rev=328140&view=rev
Log:
[InstSimplify] fp_binop X, NaN --> NaN

We propagate the existing NaN value when possible.

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


Modified:
    llvm/trunk/lib/Analysis/InstructionSimplify.cpp
    llvm/trunk/test/CodeGen/AMDGPU/imm.ll
    llvm/trunk/test/Transforms/InstSimplify/fp-nan.ll

Modified: llvm/trunk/lib/Analysis/InstructionSimplify.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Analysis/InstructionSimplify.cpp?rev=328140&r1=328139&r2=328140&view=diff
==============================================================================
--- llvm/trunk/lib/Analysis/InstructionSimplify.cpp (original)
+++ llvm/trunk/lib/Analysis/InstructionSimplify.cpp Wed Mar 21 12:31:53 2018
@@ -4163,6 +4163,28 @@ Value *llvm::SimplifyShuffleVectorInst(V
   return ::SimplifyShuffleVectorInst(Op0, Op1, Mask, RetTy, Q, RecursionLimit);
 }
 
+static Constant *propagateNaN(Constant *In) {
+  // If the input is a vector with undef elements, just return a default NaN.
+  if (!In->isNaN())
+    return ConstantFP::getNaN(In->getType());
+
+  // Propagate the existing NaN constant when possible.
+  // TODO: Should we quiet a signaling NaN?
+  return In;
+}
+
+static Constant *simplifyFPBinop(Value *Op0, Value *Op1) {
+  if (isa<UndefValue>(Op0) || isa<UndefValue>(Op1))
+    return ConstantFP::getNaN(Op0->getType());
+
+  if (match(Op0, m_NaN()))
+    return propagateNaN(cast<Constant>(Op0));
+  if (match(Op1, m_NaN()))
+    return propagateNaN(cast<Constant>(Op1));
+
+  return nullptr;
+}
+
 /// Given operands for an FAdd, see if we can fold the result.  If not, this
 /// returns null.
 static Value *SimplifyFAddInst(Value *Op0, Value *Op1, FastMathFlags FMF,
@@ -4170,8 +4192,8 @@ static Value *SimplifyFAddInst(Value *Op
   if (Constant *C = foldOrCommuteConstant(Instruction::FAdd, Op0, Op1, Q))
     return C;
 
-  if (isa<UndefValue>(Op0) || isa<UndefValue>(Op1))
-    return ConstantFP::getNaN(Op0->getType());
+  if (Constant *C = simplifyFPBinop(Op0, Op1))
+    return C;
 
   // fadd X, -0 ==> X
   if (match(Op1, m_NegZero()))
@@ -4203,8 +4225,8 @@ static Value *SimplifyFSubInst(Value *Op
   if (Constant *C = foldOrCommuteConstant(Instruction::FSub, Op0, Op1, Q))
     return C;
 
-  if (isa<UndefValue>(Op0) || isa<UndefValue>(Op1))
-    return ConstantFP::getNaN(Op0->getType());
+  if (Constant *C = simplifyFPBinop(Op0, Op1))
+    return C;
 
   // fsub X, 0 ==> X
   if (match(Op1, m_Zero()))
@@ -4238,8 +4260,8 @@ static Value *SimplifyFMulInst(Value *Op
   if (Constant *C = foldOrCommuteConstant(Instruction::FMul, Op0, Op1, Q))
     return C;
 
-  if (isa<UndefValue>(Op0) || isa<UndefValue>(Op1))
-    return ConstantFP::getNaN(Op0->getType());
+  if (Constant *C = simplifyFPBinop(Op0, Op1))
+    return C;
 
   // fmul X, 1.0 ==> X
   if (match(Op1, m_FPOne()))
@@ -4282,8 +4304,8 @@ static Value *SimplifyFDivInst(Value *Op
   if (Constant *C = foldOrCommuteConstant(Instruction::FDiv, Op0, Op1, Q))
     return C;
 
-  if (isa<UndefValue>(Op0) || isa<UndefValue>(Op1))
-    return ConstantFP::getNaN(Op0->getType());
+  if (Constant *C = simplifyFPBinop(Op0, Op1))
+    return C;
 
   // X / 1.0 -> X
   if (match(Op1, m_FPOne()))
@@ -4329,8 +4351,8 @@ static Value *SimplifyFRemInst(Value *Op
   if (Constant *C = foldOrCommuteConstant(Instruction::FRem, Op0, Op1, Q))
     return C;
 
-  if (isa<UndefValue>(Op0) || isa<UndefValue>(Op1))
-    return ConstantFP::getNaN(Op0->getType());
+  if (Constant *C = simplifyFPBinop(Op0, Op1))
+    return C;
 
   // Unlike fdiv, the result of frem always matches the sign of the dividend.
   // The constant match may include undef elements in a vector, so return a full

Modified: llvm/trunk/test/CodeGen/AMDGPU/imm.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/AMDGPU/imm.ll?rev=328140&r1=328139&r2=328140&view=diff
==============================================================================
--- llvm/trunk/test/CodeGen/AMDGPU/imm.ll (original)
+++ llvm/trunk/test/CodeGen/AMDGPU/imm.ll Wed Mar 21 12:31:53 2018
@@ -501,10 +501,9 @@ define amdgpu_kernel void @add_inline_im
 }
 
 ; GCN-LABEL: {{^}}add_inline_imm_neg_1_f64:
-; SI: s_load_dwordx2 [[VAL:s\[[0-9]+:[0-9]+\]]], {{s\[[0-9]+:[0-9]+\]}}, 0xb
-; VI: s_load_dwordx2 [[VAL:s\[[0-9]+:[0-9]+\]]], {{s\[[0-9]+:[0-9]+\]}}, 0x2c
-; GCN: v_add_f64 [[REG:v\[[0-9]+:[0-9]+\]]], [[VAL]], -1
-; GCN: buffer_store_dwordx2 [[REG]]
+; GCN: v_mov_b32_e32 v0, -1
+; GCN: v_mov_b32_e32 v1, v0
+; GCN: buffer_store_dwordx2 v[0:1]
 define amdgpu_kernel void @add_inline_imm_neg_1_f64(double addrspace(1)* %out, double %x) {
   %y = fadd double %x, 0xffffffffffffffff
   store double %y, double addrspace(1)* %out
@@ -512,10 +511,9 @@ define amdgpu_kernel void @add_inline_im
 }
 
 ; GCN-LABEL: {{^}}add_inline_imm_neg_2_f64:
-; SI: s_load_dwordx2 [[VAL:s\[[0-9]+:[0-9]+\]]], {{s\[[0-9]+:[0-9]+\]}}, 0xb
-; VI: s_load_dwordx2 [[VAL:s\[[0-9]+:[0-9]+\]]], {{s\[[0-9]+:[0-9]+\]}}, 0x2c
-; GCN: v_add_f64 [[REG:v\[[0-9]+:[0-9]+\]]], [[VAL]], -2
-; GCN: buffer_store_dwordx2 [[REG]]
+; GCN: v_mov_b32_e32 v0, -2
+; GCN: v_mov_b32_e32 v1, -1
+; GCN: buffer_store_dwordx2 v[0:1]
 define amdgpu_kernel void @add_inline_imm_neg_2_f64(double addrspace(1)* %out, double %x) {
   %y = fadd double %x, 0xfffffffffffffffe
   store double %y, double addrspace(1)* %out
@@ -523,10 +521,9 @@ define amdgpu_kernel void @add_inline_im
 }
 
 ; GCN-LABEL: {{^}}add_inline_imm_neg_16_f64:
-; SI: s_load_dwordx2 [[VAL:s\[[0-9]+:[0-9]+\]]], {{s\[[0-9]+:[0-9]+\]}}, 0xb
-; VI: s_load_dwordx2 [[VAL:s\[[0-9]+:[0-9]+\]]], {{s\[[0-9]+:[0-9]+\]}}, 0x2c
-; GCN: v_add_f64 [[REG:v\[[0-9]+:[0-9]+\]]], [[VAL]], -16
-; GCN: buffer_store_dwordx2 [[REG]]
+; GCN: v_mov_b32_e32 v0, -16
+; GCN: v_mov_b32_e32 v1, -1
+; GCN: buffer_store_dwordx2 v[0:1]
 define amdgpu_kernel void @add_inline_imm_neg_16_f64(double addrspace(1)* %out, double %x) {
   %y = fadd double %x, 0xfffffffffffffff0
   store double %y, double addrspace(1)* %out

Modified: llvm/trunk/test/Transforms/InstSimplify/fp-nan.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Transforms/InstSimplify/fp-nan.ll?rev=328140&r1=328139&r2=328140&view=diff
==============================================================================
--- llvm/trunk/test/Transforms/InstSimplify/fp-nan.ll (original)
+++ llvm/trunk/test/Transforms/InstSimplify/fp-nan.ll Wed Mar 21 12:31:53 2018
@@ -5,8 +5,7 @@
 
 define double @fadd_nan_op0(double %x) {
 ; CHECK-LABEL: @fadd_nan_op0(
-; CHECK-NEXT:    [[R:%.*]] = fadd double 0x7FF8000000000000, [[X:%.*]]
-; CHECK-NEXT:    ret double [[R]]
+; CHECK-NEXT:    ret double 0x7FF8000000000000
 ;
   %r = fadd double 0x7FF8000000000000, %x
   ret double %r
@@ -16,8 +15,7 @@ define double @fadd_nan_op0(double %x) {
 
 define double @fadd_nan_op1(double %x) {
 ; CHECK-LABEL: @fadd_nan_op1(
-; CHECK-NEXT:    [[R:%.*]] = fadd double [[X:%.*]], 0xFFF8000000000000
-; CHECK-NEXT:    ret double [[R]]
+; CHECK-NEXT:    ret double 0xFFF8000000000000
 ;
   %r = fadd double %x, 0xFFF8000000000000
   ret double %r
@@ -27,8 +25,7 @@ define double @fadd_nan_op1(double %x) {
 
 define float @fsub_nan_op0(float %x) {
 ; CHECK-LABEL: @fsub_nan_op0(
-; CHECK-NEXT:    [[R:%.*]] = fsub float 0x7FFFFF0000000000, [[X:%.*]]
-; CHECK-NEXT:    ret float [[R]]
+; CHECK-NEXT:    ret float 0x7FFFFF0000000000
 ;
   %r = fsub float 0x7FFFFF0000000000, %x
   ret float %r
@@ -38,8 +35,7 @@ define float @fsub_nan_op0(float %x) {
 
 define float @fsub_nan_op1(float %x) {
 ; CHECK-LABEL: @fsub_nan_op1(
-; CHECK-NEXT:    [[R:%.*]] = fsub float [[X:%.*]], 0x7FF1000000000000
-; CHECK-NEXT:    ret float [[R]]
+; CHECK-NEXT:    ret float 0x7FF1000000000000
 ;
   %r = fsub float %x, 0x7FF1000000000000
   ret float %r
@@ -49,8 +45,7 @@ define float @fsub_nan_op1(float %x) {
 
 define double @fmul_nan_op0(double %x) {
 ; CHECK-LABEL: @fmul_nan_op0(
-; CHECK-NEXT:    [[R:%.*]] = fmul double 0xFFF0000000000001, [[X:%.*]]
-; CHECK-NEXT:    ret double [[R]]
+; CHECK-NEXT:    ret double 0xFFF0000000000001
 ;
   %r = fmul double 0xFFF0000000000001, %x
   ret double %r
@@ -60,8 +55,7 @@ define double @fmul_nan_op0(double %x) {
 
 define <2 x float> @fmul_nan_op1(<2 x float> %x) {
 ; CHECK-LABEL: @fmul_nan_op1(
-; CHECK-NEXT:    [[R:%.*]] = fmul <2 x float> [[X:%.*]], <float 0x7FF8000000000000, float 0x7FF8000000000000>
-; CHECK-NEXT:    ret <2 x float> [[R]]
+; CHECK-NEXT:    ret <2 x float> <float 0x7FF8000000000000, float 0x7FF8000000000000>
 ;
   %r = fmul <2 x float> %x, <float 0x7FF8000000000000, float 0x7FF8000000000000>
   ret <2 x float> %r
@@ -71,8 +65,7 @@ define <2 x float> @fmul_nan_op1(<2 x fl
 
 define <2 x double> @fdiv_nan_op0(<2 x double> %x) {
 ; CHECK-LABEL: @fdiv_nan_op0(
-; CHECK-NEXT:    [[R:%.*]] = fdiv <2 x double> <double 0xFFF800000000000F, double 0xFFF800000000000F>, [[X:%.*]]
-; CHECK-NEXT:    ret <2 x double> [[R]]
+; CHECK-NEXT:    ret <2 x double> <double 0xFFF800000000000F, double 0xFFF800000000000F>
 ;
   %r = fdiv <2 x double> <double 0xFFF800000000000F, double 0xFFF800000000000F>, %x
   ret <2 x double>  %r
@@ -82,8 +75,7 @@ define <2 x double> @fdiv_nan_op0(<2 x d
 
 define <2 x half> @fdiv_nan_op1(<2 x half> %x) {
 ; CHECK-LABEL: @fdiv_nan_op1(
-; CHECK-NEXT:    [[R:%.*]] = fdiv <2 x half> [[X:%.*]], <half 0xH7FFF, half 0xHFF00>
-; CHECK-NEXT:    ret <2 x half> [[R]]
+; CHECK-NEXT:    ret <2 x half> <half 0xH7FFF, half 0xHFF00>
 ;
   %r = fdiv <2 x half> %x, <half 0xH7FFF, half 0xHFF00>
   ret <2 x half> %r
@@ -93,8 +85,7 @@ define <2 x half> @fdiv_nan_op1(<2 x hal
 
 define <2 x double> @frem_nan_op0(<2 x double> %x) {
 ; CHECK-LABEL: @frem_nan_op0(
-; CHECK-NEXT:    [[R:%.*]] = frem <2 x double> <double 0xFFFF000000000000, double undef>, [[X:%.*]]
-; CHECK-NEXT:    ret <2 x double> [[R]]
+; CHECK-NEXT:    ret <2 x double> <double 0x7FF8000000000000, double 0x7FF8000000000000>
 ;
   %r = frem <2 x double> <double 0xFFFF000000000000, double undef>, %x
   ret <2 x double> %r
@@ -102,8 +93,7 @@ define <2 x double> @frem_nan_op0(<2 x d
 
 define float @frem_nan_op1(float %x) {
 ; CHECK-LABEL: @frem_nan_op1(
-; CHECK-NEXT:    [[R:%.*]] = frem float [[X:%.*]], 0x7FF8000000000000
-; CHECK-NEXT:    ret float [[R]]
+; CHECK-NEXT:    ret float 0x7FF8000000000000
 ;
   %r = frem float %x, 0x7FF8000000000000
   ret float %r
@@ -131,8 +121,7 @@ define <2 x double> @fneg_nan_2(<2 x dou
 
 define float @fadd_nan_op0_nnan(float %x) {
 ; CHECK-LABEL: @fadd_nan_op0_nnan(
-; CHECK-NEXT:    [[R:%.*]] = fadd nnan float 0x7FF8000000000000, [[X:%.*]]
-; CHECK-NEXT:    ret float [[R]]
+; CHECK-NEXT:    ret float 0x7FF8000000000000
 ;
   %r = fadd nnan float 0x7FF8000000000000, %x
   ret float %r
@@ -140,8 +129,7 @@ define float @fadd_nan_op0_nnan(float %x
 
 define float @fadd_nan_op1_fast(float %x) {
 ; CHECK-LABEL: @fadd_nan_op1_fast(
-; CHECK-NEXT:    [[R:%.*]] = fadd fast float [[X:%.*]], 0x7FF8000000000000
-; CHECK-NEXT:    ret float [[R]]
+; CHECK-NEXT:    ret float 0x7FF8000000000000
 ;
   %r = fadd fast float %x, 0x7FF8000000000000
   ret float %r
@@ -149,8 +137,7 @@ define float @fadd_nan_op1_fast(float %x
 
 define float @fsub_nan_op0_fast(float %x) {
 ; CHECK-LABEL: @fsub_nan_op0_fast(
-; CHECK-NEXT:    [[R:%.*]] = fsub fast float 0x7FF8000000000000, [[X:%.*]]
-; CHECK-NEXT:    ret float [[R]]
+; CHECK-NEXT:    ret float 0x7FF8000000000000
 ;
   %r = fsub fast float 0x7FF8000000000000, %x
   ret float %r
@@ -158,8 +145,7 @@ define float @fsub_nan_op0_fast(float %x
 
 define float @fsub_nan_op1_nnan(float %x) {
 ; CHECK-LABEL: @fsub_nan_op1_nnan(
-; CHECK-NEXT:    [[R:%.*]] = fsub nnan float [[X:%.*]], 0x7FF8000000000000
-; CHECK-NEXT:    ret float [[R]]
+; CHECK-NEXT:    ret float 0x7FF8000000000000
 ;
   %r = fsub nnan float %x, 0x7FF8000000000000
   ret float %r
@@ -167,8 +153,7 @@ define float @fsub_nan_op1_nnan(float %x
 
 define float @fmul_nan_op0_nnan(float %x) {
 ; CHECK-LABEL: @fmul_nan_op0_nnan(
-; CHECK-NEXT:    [[R:%.*]] = fmul nnan float 0x7FF8000000000000, [[X:%.*]]
-; CHECK-NEXT:    ret float [[R]]
+; CHECK-NEXT:    ret float 0x7FF8000000000000
 ;
   %r = fmul nnan float 0x7FF8000000000000, %x
   ret float %r
@@ -176,8 +161,7 @@ define float @fmul_nan_op0_nnan(float %x
 
 define float @fmul_nan_op1_fast(float %x) {
 ; CHECK-LABEL: @fmul_nan_op1_fast(
-; CHECK-NEXT:    [[R:%.*]] = fmul fast float [[X:%.*]], 0x7FF8000000000000
-; CHECK-NEXT:    ret float [[R]]
+; CHECK-NEXT:    ret float 0x7FF8000000000000
 ;
   %r = fmul fast float %x, 0x7FF8000000000000
   ret float %r
@@ -185,8 +169,7 @@ define float @fmul_nan_op1_fast(float %x
 
 define float @fdiv_nan_op0_fast(float %x) {
 ; CHECK-LABEL: @fdiv_nan_op0_fast(
-; CHECK-NEXT:    [[R:%.*]] = fdiv fast float 0x7FF8000000000000, [[X:%.*]]
-; CHECK-NEXT:    ret float [[R]]
+; CHECK-NEXT:    ret float 0x7FF8000000000000
 ;
   %r = fdiv fast float 0x7FF8000000000000, %x
   ret float %r
@@ -194,8 +177,7 @@ define float @fdiv_nan_op0_fast(float %x
 
 define float @fdiv_nan_op1_nnan(float %x) {
 ; CHECK-LABEL: @fdiv_nan_op1_nnan(
-; CHECK-NEXT:    [[R:%.*]] = fdiv nnan float [[X:%.*]], 0x7FF8000000000000
-; CHECK-NEXT:    ret float [[R]]
+; CHECK-NEXT:    ret float 0x7FF8000000000000
 ;
   %r = fdiv nnan float %x, 0x7FF8000000000000
   ret float %r
@@ -203,8 +185,7 @@ define float @fdiv_nan_op1_nnan(float %x
 
 define float @frem_nan_op0_nnan(float %x) {
 ; CHECK-LABEL: @frem_nan_op0_nnan(
-; CHECK-NEXT:    [[R:%.*]] = frem nnan float 0x7FF8000000000000, [[X:%.*]]
-; CHECK-NEXT:    ret float [[R]]
+; CHECK-NEXT:    ret float 0x7FF8000000000000
 ;
   %r = frem nnan float 0x7FF8000000000000, %x
   ret float %r
@@ -212,8 +193,7 @@ define float @frem_nan_op0_nnan(float %x
 
 define float @frem_nan_op1_fast(float %x) {
 ; CHECK-LABEL: @frem_nan_op1_fast(
-; CHECK-NEXT:    [[R:%.*]] = frem fast float [[X:%.*]], 0x7FF8000000000000
-; CHECK-NEXT:    ret float [[R]]
+; CHECK-NEXT:    ret float 0x7FF8000000000000
 ;
   %r = frem fast float %x, 0x7FF8000000000000
   ret float %r




More information about the llvm-commits mailing list