This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
[PATCH, x86_64]: Fix PR target/31167
- From: Uros Bizjak <ubizjak at gmail dot com>
- To: GCC Patches <gcc-patches at gcc dot gnu dot org>
- Date: Wed, 14 Mar 2007 19:15:13 +0100
- Subject: [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