[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