diff --git a/llvm/lib/Analysis/InstructionSimplify.cpp b/llvm/lib/Analysis/InstructionSimplify.cpp --- a/llvm/lib/Analysis/InstructionSimplify.cpp +++ b/llvm/lib/Analysis/InstructionSimplify.cpp @@ -4807,12 +4807,16 @@ } /// Perform folds that are common to any floating-point operation. This implies -/// transforms based on undef/NaN because the operation itself makes no +/// transforms based on poison/undef/NaN because the operation itself makes no /// difference to the result. -static Constant *simplifyFPOp(ArrayRef Ops, - FastMathFlags FMF, +static Constant *simplifyFPOp(ArrayRef Ops, FastMathFlags FMF, const SimplifyQuery &Q) { for (Value *V : Ops) { + // Poison is independent of anything else. It always propagates from an + // operand to a math result. + if (match(V, m_Poison())) + return PoisonValue::get(V->getType()); + bool IsNan = match(V, m_NaN()); bool IsInf = match(V, m_Inf()); bool IsUndef = Q.isUndefValue(V); diff --git a/llvm/test/Transforms/InstSimplify/call.ll b/llvm/test/Transforms/InstSimplify/call.ll --- a/llvm/test/Transforms/InstSimplify/call.ll +++ b/llvm/test/Transforms/InstSimplify/call.ll @@ -953,7 +953,7 @@ define double @fma_poison_op0(double %x, double %y) { ; CHECK-LABEL: @fma_poison_op0( -; CHECK-NEXT: ret double 0x7FF8000000000000 +; CHECK-NEXT: ret double poison ; %r = call double @llvm.fma.f64(double poison, double %x, double %y) ret double %r @@ -969,7 +969,7 @@ define double @fma_poison_op1(double %x, double %y) { ; CHECK-LABEL: @fma_poison_op1( -; CHECK-NEXT: ret double 0x7FF8000000000000 +; CHECK-NEXT: ret double poison ; %r = call double @llvm.fma.f64(double %x, double poison, double %y) ret double %r @@ -985,7 +985,7 @@ define double @fma_poison_op2(double %x, double %y) { ; CHECK-LABEL: @fma_poison_op2( -; CHECK-NEXT: ret double 0x7FF8000000000000 +; CHECK-NEXT: ret double poison ; %r = call double @llvm.fma.f64(double %x, double %y, double poison) ret double %r @@ -1001,7 +1001,7 @@ define double @fmuladd_poison_op0(double %x, double %y) { ; CHECK-LABEL: @fmuladd_poison_op0( -; CHECK-NEXT: ret double 0x7FF8000000000000 +; CHECK-NEXT: ret double poison ; %r = call double @llvm.fmuladd.f64(double poison, double %x, double %y) ret double %r @@ -1017,7 +1017,7 @@ define double @fmuladd_poison_op1(double %x, double %y) { ; CHECK-LABEL: @fmuladd_poison_op1( -; CHECK-NEXT: ret double 0x7FF8000000000000 +; CHECK-NEXT: ret double poison ; %r = call double @llvm.fmuladd.f64(double %x, double poison, double %y) ret double %r @@ -1033,7 +1033,7 @@ define double @fmuladd_poison_op2(double %x, double %y) { ; CHECK-LABEL: @fmuladd_poison_op2( -; CHECK-NEXT: ret double 0x7FF8000000000000 +; CHECK-NEXT: ret double poison ; %r = call double @llvm.fmuladd.f64(double %x, double %y, double poison) ret double %r diff --git a/llvm/test/Transforms/InstSimplify/fp-undef-poison.ll b/llvm/test/Transforms/InstSimplify/fp-undef-poison.ll --- a/llvm/test/Transforms/InstSimplify/fp-undef-poison.ll +++ b/llvm/test/Transforms/InstSimplify/fp-undef-poison.ll @@ -1,8 +1,6 @@ ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py ; RUN: opt < %s -instsimplify -S | FileCheck %s -; TODO: the instructions with poison operands should return poison - define float @fadd_undef_op0(float %x) { ; CHECK-LABEL: @fadd_undef_op0( ; CHECK-NEXT: ret float 0x7FF8000000000000 @@ -13,7 +11,7 @@ define float @fadd_poison_op0(float %x) { ; CHECK-LABEL: @fadd_poison_op0( -; CHECK-NEXT: ret float 0x7FF8000000000000 +; CHECK-NEXT: ret float poison ; %r = fadd float poison, %x ret float %r @@ -29,7 +27,7 @@ define float @fadd_poison_op1(float %x) { ; CHECK-LABEL: @fadd_poison_op1( -; CHECK-NEXT: ret float 0x7FF8000000000000 +; CHECK-NEXT: ret float poison ; %r = fadd float %x, poison ret float %r @@ -45,7 +43,7 @@ define float @fsub_poison_op0(float %x) { ; CHECK-LABEL: @fsub_poison_op0( -; CHECK-NEXT: ret float 0x7FF8000000000000 +; CHECK-NEXT: ret float poison ; %r = fsub float poison, %x ret float %r @@ -61,7 +59,7 @@ define float @fsub_poison_op1(float %x) { ; CHECK-LABEL: @fsub_poison_op1( -; CHECK-NEXT: ret float 0x7FF8000000000000 +; CHECK-NEXT: ret float poison ; %r = fsub float %x, poison ret float %r @@ -77,7 +75,7 @@ define float @fmul_poison_op0(float %x) { ; CHECK-LABEL: @fmul_poison_op0( -; CHECK-NEXT: ret float 0x7FF8000000000000 +; CHECK-NEXT: ret float poison ; %r = fmul float poison, %x ret float %r @@ -93,7 +91,7 @@ define float @fmul_poison_op1(float %x) { ; CHECK-LABEL: @fmul_poison_op1( -; CHECK-NEXT: ret float 0x7FF8000000000000 +; CHECK-NEXT: ret float poison ; %r = fmul float %x, poison ret float %r @@ -109,7 +107,7 @@ define float @fdiv_poison_op0(float %x) { ; CHECK-LABEL: @fdiv_poison_op0( -; CHECK-NEXT: ret float 0x7FF8000000000000 +; CHECK-NEXT: ret float poison ; %r = fdiv float poison, %x ret float %r @@ -125,7 +123,7 @@ define float @fdiv_poison_op1(float %x) { ; CHECK-LABEL: @fdiv_poison_op1( -; CHECK-NEXT: ret float 0x7FF8000000000000 +; CHECK-NEXT: ret float poison ; %r = fdiv float %x, poison ret float %r @@ -141,7 +139,7 @@ define float @frem_poison_op0(float %x) { ; CHECK-LABEL: @frem_poison_op0( -; CHECK-NEXT: ret float 0x7FF8000000000000 +; CHECK-NEXT: ret float poison ; %r = frem float poison, %x ret float %r @@ -157,7 +155,7 @@ define float @frem_poison_op1(float %x) { ; CHECK-LABEL: @frem_poison_op1( -; CHECK-NEXT: ret float 0x7FF8000000000000 +; CHECK-NEXT: ret float poison ; %r = frem float %x, poison ret float %r