[DAGCombiner] restrict (float)((int) f) --> ftrunc with no-signed-zeros
As noted in the D44909 review, the transform from (fptosi+sitofp) to ftrunc
can produce -0.0 where the original code does not:
#include <stdio.h>
int main(int argc) {
float x;
x = -0.8 * argc;
printf("%f\n", (float)((int)x));
return 0;
}
$ clang -O0 -mavx fp.c ; ./a.out
0.000000
$ clang -O1 -mavx fp.c ; ./a.out
-0.000000
Ideally, we'd use IR/node flags to predicate the transform, but the IR parser
doesn't currently allow fast-math-flags on the cast instructions. So for now,
just use the function attribute that corresponds to clang's "-fno-signed-zeros"
option.
Differential Revision: https://reviews.llvm.org/D48085
llvm-svn: 335761
diff --git a/llvm/test/CodeGen/PowerPC/fp-int128-fp-combine.ll b/llvm/test/CodeGen/PowerPC/fp-int128-fp-combine.ll
index 4a36f24..1b403a6 100644
--- a/llvm/test/CodeGen/PowerPC/fp-int128-fp-combine.ll
+++ b/llvm/test/CodeGen/PowerPC/fp-int128-fp-combine.ll
@@ -2,9 +2,35 @@
; RUN: llc -O0 -mtriple=powerpc64le-unknown-linux-gnu < %s | FileCheck %s
; xscvdpsxds should NOT be emitted, since it saturates the result down to i64.
+; We can't use friz here because it may return -0.0 where the original code doesn't.
+
define float @f_i128_f(float %v) {
; CHECK-LABEL: f_i128_f:
; CHECK: # %bb.0: # %entry
+; CHECK-NEXT: mflr 0
+; CHECK-NEXT: std 0, 16(1)
+; CHECK-NEXT: stdu 1, -32(1)
+; CHECK-NEXT: .cfi_def_cfa_offset 32
+; CHECK-NEXT: .cfi_offset lr, 16
+; CHECK-NEXT: bl __fixsfti
+; CHECK-NEXT: nop
+; CHECK-NEXT: bl __floattisf
+; CHECK-NEXT: nop
+; CHECK-NEXT: addi 1, 1, 32
+; CHECK-NEXT: ld 0, 16(1)
+; CHECK-NEXT: mtlr 0
+; CHECK-NEXT: blr
+entry:
+ %a = fptosi float %v to i128
+ %b = sitofp i128 %a to float
+ ret float %b
+}
+
+; NSZ, so it's safe to friz.
+
+define float @f_i128_fi_nsz(float %v) #0 {
+; CHECK-LABEL: f_i128_fi_nsz:
+; CHECK: # %bb.0: # %entry
; CHECK-NEXT: friz 1, 1
; CHECK-NEXT: blr
entry:
@@ -12,3 +38,6 @@
%b = sitofp i128 %a to float
ret float %b
}
+
+attributes #0 = { "no-signed-zeros-fp-math"="true" }
+
diff --git a/llvm/test/CodeGen/PowerPC/fp-to-int-to-fp.ll b/llvm/test/CodeGen/PowerPC/fp-to-int-to-fp.ll
index 942bdf5..ffc626b 100644
--- a/llvm/test/CodeGen/PowerPC/fp-to-int-to-fp.ll
+++ b/llvm/test/CodeGen/PowerPC/fp-to-int-to-fp.ll
@@ -62,5 +62,5 @@
; FPCVT: blr
}
-attributes #0 = { nounwind readnone }
+attributes #0 = { nounwind readnone "no-signed-zeros-fp-math"="true" }
diff --git a/llvm/test/CodeGen/PowerPC/ftrunc-vec.ll b/llvm/test/CodeGen/PowerPC/ftrunc-vec.ll
index ef529ed..f860c37 100644
--- a/llvm/test/CodeGen/PowerPC/ftrunc-vec.ll
+++ b/llvm/test/CodeGen/PowerPC/ftrunc-vec.ll
@@ -1,7 +1,7 @@
; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
; RUN: llc -mcpu=pwr8 -mtriple=powerpc64le-unknown-unknown -verify-machineinstrs < %s | FileCheck %s
-define <4 x float> @truncf32(<4 x float> %a) {
+define <4 x float> @truncf32(<4 x float> %a) #0 {
; CHECK-LABEL: truncf32:
; CHECK: # %bb.0:
; CHECK-NEXT: xvrspiz 34, 34
@@ -11,7 +11,7 @@
ret <4 x float> %t1
}
-define <2 x double> @truncf64(<2 x double> %a) {
+define <2 x double> @truncf64(<2 x double> %a) #0 {
; CHECK-LABEL: truncf64:
; CHECK: # %bb.0:
; CHECK-NEXT: xvrdpiz 34, 34
@@ -21,7 +21,7 @@
ret <2 x double> %t1
}
-define <4 x float> @truncf32u(<4 x float> %a) {
+define <4 x float> @truncf32u(<4 x float> %a) #0 {
; CHECK-LABEL: truncf32u:
; CHECK: # %bb.0:
; CHECK-NEXT: xvrspiz 34, 34
@@ -31,7 +31,7 @@
ret <4 x float> %t1
}
-define <2 x double> @truncf64u(<2 x double> %a) {
+define <2 x double> @truncf64u(<2 x double> %a) #0 {
; CHECK-LABEL: truncf64u:
; CHECK: # %bb.0:
; CHECK-NEXT: xvrdpiz 34, 34
@@ -41,3 +41,5 @@
ret <2 x double> %t1
}
+attributes #0 = { "no-signed-zeros-fp-math"="true" }
+
diff --git a/llvm/test/CodeGen/PowerPC/no-extra-fp-conv-ldst.ll b/llvm/test/CodeGen/PowerPC/no-extra-fp-conv-ldst.ll
index 0bbaf34..2ae1d32 100644
--- a/llvm/test/CodeGen/PowerPC/no-extra-fp-conv-ldst.ll
+++ b/llvm/test/CodeGen/PowerPC/no-extra-fp-conv-ldst.ll
@@ -76,5 +76,5 @@
; CHECK: blr
}
-attributes #0 = { nounwind readonly }
+attributes #0 = { nounwind readonly "no-signed-zeros-fp-math"="true" }