From 31ec72a21f494c7e4553d25cd7412d34cd3d06aa Mon Sep 17 00:00:00 2001 From: Sanjay Patel Date: Wed, 16 Jun 2021 11:22:15 -0400 Subject: [PATCH] [InstSimplify] propagate poison through FP ops We already have this fold: fadd float poison, 1.0 --> poison ...via ConstantFolding, so this makes the behavior consistent if the other operand(s) are non-constant. The fold for undef was added before poison existed as a value/type in IR. This came up in D102673 / D103169 because we're trying to sort out the more complicated handling for constrained math ops. We should have the handling for the regular instructions done first, so we can build on that (or diverge as needed). Differential Revision: https://reviews.llvm.org/D104383 --- lib/Analysis/InstructionSimplify.cpp | 10 ++++++--- test/Transforms/InstSimplify/call.ll | 12 +++++----- .../InstSimplify/fp-undef-poison.ll | 22 +++++++++---------- 3 files changed, 23 insertions(+), 21 deletions(-) diff --git a/lib/Analysis/InstructionSimplify.cpp b/lib/Analysis/InstructionSimplify.cpp index 7fb7a394e86..895218bea9f 100644 --- a/lib/Analysis/InstructionSimplify.cpp +++ b/lib/Analysis/InstructionSimplify.cpp @@ -4807,12 +4807,16 @@ static Constant *propagateNaN(Constant *In) { } /// 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/test/Transforms/InstSimplify/call.ll b/test/Transforms/InstSimplify/call.ll index 99a4a96d33b..721f4941e51 100644 --- a/test/Transforms/InstSimplify/call.ll +++ b/test/Transforms/InstSimplify/call.ll @@ -953,7 +953,7 @@ define double @fma_undef_op0(double %x, double %y) { 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_undef_op1(double %x, double %y) { 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_undef_op2(double %x, double %y) { 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_undef_op0(double %x, double %y) { 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_undef_op1(double %x, double %y) { 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_undef_op2(double %x, double %y) { 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/test/Transforms/InstSimplify/fp-undef-poison.ll b/test/Transforms/InstSimplify/fp-undef-poison.ll index 129d868704c..6a8036c37b6 100644 --- a/test/Transforms/InstSimplify/fp-undef-poison.ll +++ b/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_undef_op0(float %x) { 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_undef_op1(float %x) { 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_undef_op0(float %x) { 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_undef_op1(float %x) { 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_undef_op0(float %x) { 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_undef_op1(float %x) { 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_undef_op0(float %x) { 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_undef_op1(float %x) { 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_undef_op0(float %x) { 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_undef_op1(float %x) { 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