Fix for the following bug in AVX codegen for double-to-int conversions:
authorVictor Umansky <victor.umansky@intel.com>
Thu, 26 Jan 2012 08:51:39 +0000 (08:51 +0000)
committerVictor Umansky <victor.umansky@intel.com>
Thu, 26 Jan 2012 08:51:39 +0000 (08:51 +0000)
. "fptosi" and "fptoui" IR instructions are defined with round-to-zero rounding mode.
. Currently for AVX mode for <4xdouble> and <8xdouble>  the "VCVTPD2DQ.128" and "VCVTPD2DQ.256" instructions are selected (for .fp_to_sint. DAG node operation ) by AVX codegen. However they use round-to-nearest-even rounding mode.
. Consequently, the conversion produces incorrect numbers.

The fix is to replace selection of VCVTPD2DQ instructions with VCVTTPD2DQ instructions. The latter use truncate (i.e. round-to-zero) rounding mode.
As .fp_to_sint. DAG node operation is used only for lowering of  "fptosi" and "fptoui" IR instructions, the fix in X86InstrSSE.td definition file doesn.t have an impact on other LLVM flows.

The patch includes changes in the .td file, LIT test for the changes and a fix in a legacy LIT test (which produced asm code conflicting with LLVN IR spec).

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@149056 91177308-0d34-0410-b5e6-96231b3b80d8

lib/Target/X86/X86InstrSSE.td
test/CodeGen/X86/avx-cvt.ll
test/CodeGen/X86/avx-fp2int.ll [new file with mode: 0755]

index 7b710f0928e1674a06faf9df593931143a5eacef..ac44473ca3c305ad6143ed07fbdea820801afcba 100644 (file)
@@ -4693,9 +4693,9 @@ def CVTPD2DQrr  : S3DI<0xE6, MRMSrcReg, (outs VR128:$dst), (ins VR128:$src),
                        "cvtpd2dq\t{$src, $dst|$dst, $src}", []>;
 
 def : Pat<(v4i32 (fp_to_sint (v4f64 VR256:$src))),
-          (VCVTPD2DQYrr VR256:$src)>;
+          (VCVTTPD2DQYrr VR256:$src)>;
 def : Pat<(v4i32 (fp_to_sint (memopv4f64 addr:$src))),
-          (VCVTPD2DQYrm addr:$src)>;
+          (VCVTTPD2DQYrm addr:$src)>;
 
 // Convert Packed DW Integers to Packed Double FP
 let Predicates = [HasAVX] in {
index 6c0bd58074d49ba8fd7017be32ea596f9656a073..d0a7fe01009e03fa959af2c173b20bf0fb1f84dd 100644 (file)
@@ -18,7 +18,7 @@ define <4 x double> @sitofp01(<4 x i32> %a) {
   ret <4 x double> %b
 }
 
-; CHECK: vcvtpd2dqy %ymm
+; CHECK: vcvttpd2dqy %ymm
 define <4 x i32> @fptosi01(<4 x double> %a) {
   %b = fptosi <4 x double> %a to <4 x i32>
   ret <4 x i32> %b
diff --git a/test/CodeGen/X86/avx-fp2int.ll b/test/CodeGen/X86/avx-fp2int.ll
new file mode 100755 (executable)
index 0000000..9e505bd
--- /dev/null
@@ -0,0 +1,19 @@
+; RUN: llc < %s -mtriple=i386-apple-darwin10 -mcpu=corei7-avx -mattr=+avx | FileCheck %s\r
+\r
+;; Check that FP_TO_SINT and FP_TO_UINT generate convert with truncate\r
+\r
+; CHECK: test1:\r
+; CHECK: vcvttpd2dqy\r
+; CHECK: ret\r
+; CHECK: test2:\r
+; CHECK: vcvttpd2dqy\r
+; CHECK: ret\r
+\r
+define <4 x i8> @test1(<4 x double> %d) {\r
+  %c = fptoui <4 x double> %d to <4 x i8>\r
+  ret <4 x i8> %c\r
+}\r
+define <4 x i8> @test2(<4 x double> %d) {\r
+  %c = fptosi <4 x double> %d to <4 x i8>\r
+  ret <4 x i8> %c\r
+}\r