This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[PATCH, x86_64]: Fix PR target/31167


Hello!

The problem, exposed by the testcase in the bugreport, is with TImode addti3_1 pattern and its splitter. Same problems can be expected with subti3_1, negti2_1 and their splitters.

The core of the problem is in splitter, where we split TImode immediate into two DImode immediates. Unfortunatelly, 64bit instructions can accept only 32bit immediates.

The solution is straightforward. As TImode immediates can't be split into two legal DImode values, we reject all but 32bit type "e" immediate values for affected TImode patterns.

The testcase:

--cut here--
typedef int int32_t;

int32_t round32hi (const __int128_t arg)
{
 const int SHIFT = 96;
 const int mshift = 96;
 const __int128_t M = (~(__int128_t) 0) << mshift;
 const __int128_t L = (~M) + 1;
 const __int128_t L1 = ((__int128_t) L) >> 1;
 const __int128_t Mlo = ((__int128_t) (~M)) >> 1;
 __int128_t vv = arg & M;

 if ((arg & (L1)) && ((arg & Mlo) || (arg & L)))
   vv += L;

 return (int32_t) (vv >> SHIFT);
}
--cut here--

then compiles into:

round32hi:
.LFB2:
       movabsq $-4294967296, %rax
       movq    %rsi, %r9
       xorl    %r8d, %r8d
       andq    %rax, %r9
       testl   $2147483648, %esi
       je      .L2
       movq    %rsi, %rax
       andl    $2147483647, %eax
       orq     %rdi, %rax
       je      .L8
.L4:
       xorl    %eax, %eax
       movabsq $4294967296, %rdx
       addq    %rax, %r8
       adcq    %rdx, %r9
.L2:
       movq    %r9, %r8
       sarq    $32, %r8
       movl    %r8d, %eax
       ret
       .p2align 4,,7
.L8:
       movabsq $4294967296, %rax
       testq   %rax, %rsi
       jne     .L4
       jmp     .L2


2007-03-14 Uros Bizjak <ubizjak@gmail.com>


       PR target/31167
       * config/i386/i386.md (*addti3_1, *addti3_1 splitter): Use
       x86_64_general_operand as operand[2] predicate.  Remove "iF"
       from operand constraints and use "e" constraint instead.
       (*subti3_1, *subti3_1 splitter): Ditto.
       (*negti2_1, *negti2_1 splitter): Use x86_64_general_operand as
       operand[1] predicate.

testsuite/ChangeLog

       PR target/31167
       * gcc.target/i386/pr31167.c: New test.

Patch is bootstrapped on x86_64-pc-linux-gnu, regression tested for all default languages. As this patch is pure x86_64 stuff, it needs a x86_64 maintainer approval.

Uros.
Index: testsuite/gcc.target/i386/pr31167.c
===================================================================
--- testsuite/gcc.target/i386/pr31167.c	(revision 0)
+++ testsuite/gcc.target/i386/pr31167.c	(revision 0)
@@ -0,0 +1,20 @@
+/* { dg-do compile { target x86_64-*-* } } */
+/* { dg-options "-O" } */
+
+typedef int int32_t;
+
+int32_t round32hi (const __int128_t arg)
+{
+  const int SHIFT = 96;
+  const int mshift = 96;
+  const __int128_t M = (~(__int128_t) 0) << mshift;
+  const __int128_t L = (~M) + 1;
+  const __int128_t L1 = ((__int128_t) L) >> 1;
+  const __int128_t Mlo = ((__int128_t) (~M)) >> 1;
+  __int128_t vv = arg & M;
+
+  if ((arg & (L1)) && ((arg & Mlo) || (arg & L)))
+    vv += L;
+
+  return (int32_t) (vv >> SHIFT);
+}
Index: config/i386/i386.md
===================================================================
--- config/i386/i386.md	(revision 122924)
+++ config/i386/i386.md	(working copy)
@@ -5048,7 +5048,7 @@
 (define_insn "*addti3_1"
   [(set (match_operand:TI 0 "nonimmediate_operand" "=r,o")
 	(plus:TI (match_operand:TI 1 "nonimmediate_operand" "%0,0")
-		 (match_operand:TI 2 "general_operand" "roiF,riF")))
+		 (match_operand:TI 2 "x86_64_general_operand" "roe,re")))
    (clobber (reg:CC FLAGS_REG))]
   "TARGET_64BIT && ix86_binary_operator_ok (PLUS, TImode, operands)"
   "#")
@@ -5056,7 +5056,7 @@
 (define_split
   [(set (match_operand:TI 0 "nonimmediate_operand" "")
 	(plus:TI (match_operand:TI 1 "nonimmediate_operand" "")
-		 (match_operand:TI 2 "general_operand" "")))
+		 (match_operand:TI 2 "x86_64_general_operand" "")))
    (clobber (reg:CC FLAGS_REG))]
   "TARGET_64BIT && reload_completed"
   [(parallel [(set (reg:CC FLAGS_REG) (unspec:CC [(match_dup 1) (match_dup 2)]
@@ -6782,7 +6782,7 @@
 (define_insn "*subti3_1"
   [(set (match_operand:TI 0 "nonimmediate_operand" "=r,o")
 	(minus:TI (match_operand:TI 1 "nonimmediate_operand" "0,0")
-		  (match_operand:TI 2 "general_operand" "roiF,riF")))
+		  (match_operand:TI 2 "x86_64_general_operand" "roe,re")))
    (clobber (reg:CC FLAGS_REG))]
   "TARGET_64BIT && ix86_binary_operator_ok (MINUS, TImode, operands)"
   "#")
@@ -6790,7 +6790,7 @@
 (define_split
   [(set (match_operand:TI 0 "nonimmediate_operand" "")
 	(minus:TI (match_operand:TI 1 "nonimmediate_operand" "")
-		  (match_operand:TI 2 "general_operand" "")))
+		  (match_operand:TI 2 "x86_64_general_operand" "")))
    (clobber (reg:CC FLAGS_REG))]
   "TARGET_64BIT && reload_completed"
   [(parallel [(set (reg:CC FLAGS_REG) (compare:CC (match_dup 1) (match_dup 2)))
@@ -9684,7 +9684,7 @@
 
 (define_insn "*negti2_1"
   [(set (match_operand:TI 0 "nonimmediate_operand" "=ro")
-	(neg:TI (match_operand:TI 1 "general_operand" "0")))
+	(neg:TI (match_operand:TI 1 "x86_64_general_operand" "0")))
    (clobber (reg:CC FLAGS_REG))]
   "TARGET_64BIT
    && ix86_unary_operator_ok (NEG, TImode, operands)"
@@ -9692,7 +9692,7 @@
 
 (define_split
   [(set (match_operand:TI 0 "nonimmediate_operand" "")
-	(neg:TI (match_operand:TI 1 "general_operand" "")))
+	(neg:TI (match_operand:TI 1 "x86_64_general_operand" "")))
    (clobber (reg:CC FLAGS_REG))]
   "TARGET_64BIT && reload_completed"
   [(parallel

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]