From 42227168220a642afe0e412595e5a7f6244f9b3f Mon Sep 17 00:00:00 2001 From: Sanjay Patel Date: Sat, 10 Mar 2018 16:51:28 +0000 Subject: [PATCH] [InstSimplify] fp_binop X, undef --> NaN The variable operand could be NaN, so it's always safe to propagate NaN. llvm-svn: 327212 --- llvm/lib/Analysis/InstructionSimplify.cpp | 27 +++++++------- llvm/test/Transforms/InstCombine/fsub.ll | 20 ----------- llvm/test/Transforms/InstSimplify/fp-undef.ll | 52 +++++++++++---------------- 3 files changed, 33 insertions(+), 66 deletions(-) diff --git a/llvm/lib/Analysis/InstructionSimplify.cpp b/llvm/lib/Analysis/InstructionSimplify.cpp index 8b8a041..a95a775 100644 --- a/llvm/lib/Analysis/InstructionSimplify.cpp +++ b/llvm/lib/Analysis/InstructionSimplify.cpp @@ -4156,6 +4156,9 @@ static Value *SimplifyFAddInst(Value *Op0, Value *Op1, FastMathFlags FMF, if (Constant *C = foldOrCommuteConstant(Instruction::FAdd, Op0, Op1, Q)) return C; + if (isa(Op0) || isa(Op1)) + return ConstantFP::getNaN(Op0->getType()); + // fadd X, -0 ==> X if (match(Op1, m_NegZero())) return Op0; @@ -4190,6 +4193,9 @@ static Value *SimplifyFSubInst(Value *Op0, Value *Op1, FastMathFlags FMF, if (Constant *C = foldOrCommuteConstant(Instruction::FSub, Op0, Op1, Q)) return C; + if (isa(Op0) || isa(Op1)) + return ConstantFP::getNaN(Op0->getType()); + // fsub X, 0 ==> X if (match(Op1, m_Zero())) return Op0; @@ -4222,6 +4228,9 @@ static Value *SimplifyFMulInst(Value *Op0, Value *Op1, FastMathFlags FMF, if (Constant *C = foldOrCommuteConstant(Instruction::FMul, Op0, Op1, Q)) return C; + if (isa(Op0) || isa(Op1)) + return ConstantFP::getNaN(Op0->getType()); + // fmul X, 1.0 ==> X if (match(Op1, m_FPOne())) return Op0; @@ -4260,13 +4269,8 @@ static Value *SimplifyFDivInst(Value *Op0, Value *Op1, FastMathFlags FMF, if (Constant *C = foldOrCommuteConstant(Instruction::FDiv, Op0, Op1, Q)) return C; - // undef / X -> undef (the undef could be a snan). - if (match(Op0, m_Undef())) - return Op0; - - // X / undef -> undef - if (match(Op1, m_Undef())) - return Op1; + if (isa(Op0) || isa(Op1)) + return ConstantFP::getNaN(Op0->getType()); // X / 1.0 -> X if (match(Op1, m_FPOne())) @@ -4312,13 +4316,8 @@ static Value *SimplifyFRemInst(Value *Op0, Value *Op1, FastMathFlags FMF, if (Constant *C = foldOrCommuteConstant(Instruction::FRem, Op0, Op1, Q)) return C; - // undef % X -> undef (the undef could be a snan). - if (match(Op0, m_Undef())) - return Op0; - - // X % undef -> undef - if (match(Op1, m_Undef())) - return Op1; + if (isa(Op0) || isa(Op1)) + return ConstantFP::getNaN(Op0->getType()); // 0 % X -> 0 // Requires that NaNs are off (X could be zero) and signed zeroes are diff --git a/llvm/test/Transforms/InstCombine/fsub.ll b/llvm/test/Transforms/InstCombine/fsub.ll index d6b5e3a..e7b5a07 100644 --- a/llvm/test/Transforms/InstCombine/fsub.ll +++ b/llvm/test/Transforms/InstCombine/fsub.ll @@ -27,23 +27,3 @@ define double @test2(double %x, double %y) nounwind { ret double %t2 } -define float @fsub_undef(float %val) { -; CHECK-LABEL: @fsub_undef( -; CHECK-NEXT: [[SUB:%.*]] = fsub float [[VAL:%.*]], undef -; CHECK-NEXT: ret float [[SUB]] -; - %sub = fsub float %val, undef - ret float %sub -} - -; XXX - Why doesn't this fold to undef? - -define float @fsub_fast_undef(float %val) { -; CHECK-LABEL: @fsub_fast_undef( -; CHECK-NEXT: [[SUB:%.*]] = fsub fast float [[VAL:%.*]], undef -; CHECK-NEXT: ret float [[SUB]] -; - %sub = fsub fast float %val, undef - ret float %sub -} - diff --git a/llvm/test/Transforms/InstSimplify/fp-undef.ll b/llvm/test/Transforms/InstSimplify/fp-undef.ll index 8dbb761..58c1825 100644 --- a/llvm/test/Transforms/InstSimplify/fp-undef.ll +++ b/llvm/test/Transforms/InstSimplify/fp-undef.ll @@ -3,8 +3,7 @@ define float @fadd_undef_op0(float %x) { ; CHECK-LABEL: @fadd_undef_op0( -; CHECK-NEXT: [[R:%.*]] = fadd float undef, [[X:%.*]] -; CHECK-NEXT: ret float [[R]] +; CHECK-NEXT: ret float 0x7FF8000000000000 ; %r = fadd float undef, %x ret float %r @@ -12,8 +11,7 @@ define float @fadd_undef_op0(float %x) { define float @fadd_undef_op1(float %x) { ; CHECK-LABEL: @fadd_undef_op1( -; CHECK-NEXT: [[R:%.*]] = fadd float [[X:%.*]], undef -; CHECK-NEXT: ret float [[R]] +; CHECK-NEXT: ret float 0x7FF8000000000000 ; %r = fadd float %x, undef ret float %r @@ -21,8 +19,7 @@ define float @fadd_undef_op1(float %x) { define float @fsub_undef_op0(float %x) { ; CHECK-LABEL: @fsub_undef_op0( -; CHECK-NEXT: [[R:%.*]] = fsub float undef, [[X:%.*]] -; CHECK-NEXT: ret float [[R]] +; CHECK-NEXT: ret float 0x7FF8000000000000 ; %r = fsub float undef, %x ret float %r @@ -30,8 +27,7 @@ define float @fsub_undef_op0(float %x) { define float @fsub_undef_op1(float %x) { ; CHECK-LABEL: @fsub_undef_op1( -; CHECK-NEXT: [[R:%.*]] = fsub float [[X:%.*]], undef -; CHECK-NEXT: ret float [[R]] +; CHECK-NEXT: ret float 0x7FF8000000000000 ; %r = fsub float %x, undef ret float %r @@ -39,8 +35,7 @@ define float @fsub_undef_op1(float %x) { define float @fmul_undef_op0(float %x) { ; CHECK-LABEL: @fmul_undef_op0( -; CHECK-NEXT: [[R:%.*]] = fmul float undef, [[X:%.*]] -; CHECK-NEXT: ret float [[R]] +; CHECK-NEXT: ret float 0x7FF8000000000000 ; %r = fmul float undef, %x ret float %r @@ -48,8 +43,7 @@ define float @fmul_undef_op0(float %x) { define float @fmul_undef_op1(float %x) { ; CHECK-LABEL: @fmul_undef_op1( -; CHECK-NEXT: [[R:%.*]] = fmul float [[X:%.*]], undef -; CHECK-NEXT: ret float [[R]] +; CHECK-NEXT: ret float 0x7FF8000000000000 ; %r = fmul float %x, undef ret float %r @@ -57,7 +51,7 @@ define float @fmul_undef_op1(float %x) { define float @fdiv_undef_op0(float %x) { ; CHECK-LABEL: @fdiv_undef_op0( -; CHECK-NEXT: ret float undef +; CHECK-NEXT: ret float 0x7FF8000000000000 ; %r = fdiv float undef, %x ret float %r @@ -65,7 +59,7 @@ define float @fdiv_undef_op0(float %x) { define float @fdiv_undef_op1(float %x) { ; CHECK-LABEL: @fdiv_undef_op1( -; CHECK-NEXT: ret float undef +; CHECK-NEXT: ret float 0x7FF8000000000000 ; %r = fdiv float %x, undef ret float %r @@ -73,7 +67,7 @@ define float @fdiv_undef_op1(float %x) { define float @frem_undef_op0(float %x) { ; CHECK-LABEL: @frem_undef_op0( -; CHECK-NEXT: ret float undef +; CHECK-NEXT: ret float 0x7FF8000000000000 ; %r = frem float undef, %x ret float %r @@ -81,7 +75,7 @@ define float @frem_undef_op0(float %x) { define float @frem_undef_op1(float %x) { ; CHECK-LABEL: @frem_undef_op1( -; CHECK-NEXT: ret float undef +; CHECK-NEXT: ret float 0x7FF8000000000000 ; %r = frem float %x, undef ret float %r @@ -91,8 +85,7 @@ define float @frem_undef_op1(float %x) { define float @fadd_undef_op0_nnan(float %x) { ; CHECK-LABEL: @fadd_undef_op0_nnan( -; CHECK-NEXT: [[R:%.*]] = fadd nnan float undef, [[X:%.*]] -; CHECK-NEXT: ret float [[R]] +; CHECK-NEXT: ret float 0x7FF8000000000000 ; %r = fadd nnan float undef, %x ret float %r @@ -100,8 +93,7 @@ define float @fadd_undef_op0_nnan(float %x) { define float @fadd_undef_op1_fast(float %x) { ; CHECK-LABEL: @fadd_undef_op1_fast( -; CHECK-NEXT: [[R:%.*]] = fadd fast float [[X:%.*]], undef -; CHECK-NEXT: ret float [[R]] +; CHECK-NEXT: ret float 0x7FF8000000000000 ; %r = fadd fast float %x, undef ret float %r @@ -109,8 +101,7 @@ define float @fadd_undef_op1_fast(float %x) { define float @fsub_undef_op0_fast(float %x) { ; CHECK-LABEL: @fsub_undef_op0_fast( -; CHECK-NEXT: [[R:%.*]] = fsub fast float undef, [[X:%.*]] -; CHECK-NEXT: ret float [[R]] +; CHECK-NEXT: ret float 0x7FF8000000000000 ; %r = fsub fast float undef, %x ret float %r @@ -118,8 +109,7 @@ define float @fsub_undef_op0_fast(float %x) { define float @fsub_undef_op1_nnan(float %x) { ; CHECK-LABEL: @fsub_undef_op1_nnan( -; CHECK-NEXT: [[R:%.*]] = fsub nnan float [[X:%.*]], undef -; CHECK-NEXT: ret float [[R]] +; CHECK-NEXT: ret float 0x7FF8000000000000 ; %r = fsub nnan float %x, undef ret float %r @@ -127,8 +117,7 @@ define float @fsub_undef_op1_nnan(float %x) { define float @fmul_undef_op0_nnan(float %x) { ; CHECK-LABEL: @fmul_undef_op0_nnan( -; CHECK-NEXT: [[R:%.*]] = fmul nnan float undef, [[X:%.*]] -; CHECK-NEXT: ret float [[R]] +; CHECK-NEXT: ret float 0x7FF8000000000000 ; %r = fmul nnan float undef, %x ret float %r @@ -136,8 +125,7 @@ define float @fmul_undef_op0_nnan(float %x) { define float @fmul_undef_op1_fast(float %x) { ; CHECK-LABEL: @fmul_undef_op1_fast( -; CHECK-NEXT: [[R:%.*]] = fmul fast float [[X:%.*]], undef -; CHECK-NEXT: ret float [[R]] +; CHECK-NEXT: ret float 0x7FF8000000000000 ; %r = fmul fast float %x, undef ret float %r @@ -145,7 +133,7 @@ define float @fmul_undef_op1_fast(float %x) { define float @fdiv_undef_op0_fast(float %x) { ; CHECK-LABEL: @fdiv_undef_op0_fast( -; CHECK-NEXT: ret float undef +; CHECK-NEXT: ret float 0x7FF8000000000000 ; %r = fdiv fast float undef, %x ret float %r @@ -153,7 +141,7 @@ define float @fdiv_undef_op0_fast(float %x) { define float @fdiv_undef_op1_nnan(float %x) { ; CHECK-LABEL: @fdiv_undef_op1_nnan( -; CHECK-NEXT: ret float undef +; CHECK-NEXT: ret float 0x7FF8000000000000 ; %r = fdiv nnan float %x, undef ret float %r @@ -161,7 +149,7 @@ define float @fdiv_undef_op1_nnan(float %x) { define float @frem_undef_op0_nnan(float %x) { ; CHECK-LABEL: @frem_undef_op0_nnan( -; CHECK-NEXT: ret float undef +; CHECK-NEXT: ret float 0x7FF8000000000000 ; %r = frem nnan float undef, %x ret float %r @@ -169,7 +157,7 @@ define float @frem_undef_op0_nnan(float %x) { define float @frem_undef_op1_fast(float %x) { ; CHECK-LABEL: @frem_undef_op1_fast( -; CHECK-NEXT: ret float undef +; CHECK-NEXT: ret float 0x7FF8000000000000 ; %r = frem fast float %x, undef ret float %r -- 2.7.4