Re: [PATCH, i386]: Fix PR78626, wrong code with -fschedule-insns

2016-11-11 Thread Uros Bizjak
On Wed, Nov 9, 2016 at 8:25 PM, Uros Bizjak  wrote:
> Hello!
>
> We need earlyclobber on output operand of doubleword shift insns,
> since we have to prevent (partial) output matching %ecx as count
> argument.
>
> 2016-11-09  Uros Bizjak  
>
> PR target/78262
> * config/i386/i386.md (*3_doubleword): Mark
> operand 0 as earlyclobber.
>
> testsuite/ChangeLog:
>
> 2016-11-09  Uros Bizjak  
>
> PR target/78262
> * gcc.target/i386/pr78262.c: New test.
>
> Bootstrapped and regression tested on x86_64-linux-gnu {,-m32}.
>
> Committed to mainline, will be backported to release branches.

Actually, we have also to add earlyclobber to all operand 0
alternatives of *ashl3_doubleword pattern to prevent similar
issue.

PR target/78262
* config/i386/i386.md (*3_doubleword): Mark
operand 0 as earlyclobber.
(*ashl3_doubleword): Ditto for all operand 0 alternatives.

I have amended the patch with attached part.

Uros.
Index: config/i386/i386.md
===
--- config/i386/i386.md (revision 242076)
+++ config/i386/i386.md (working copy)
@@ -9704,7 +9704,7 @@
   "ix86_expand_binary_operator (ASHIFT, mode, operands); DONE;")
 
 (define_insn "*ashl3_doubleword"
-  [(set (match_operand:DWI 0 "register_operand" "=&r,r")
+  [(set (match_operand:DWI 0 "register_operand" "=&r,&r")
(ashift:DWI (match_operand:DWI 1 "reg_or_pm1_operand" "n,0")
(match_operand:QI 2 "nonmemory_operand" "c,c")))
(clobber (reg:CC FLAGS_REG))]


[PATCH, i386]: Fix PR78626, wrong code with -fschedule-insns

2016-11-09 Thread Uros Bizjak
Hello!

We need earlyclobber on output operand of doubleword shift insns,
since we have to prevent (partial) output matching %ecx as count
argument.

2016-11-09  Uros Bizjak  

PR target/78262
* config/i386/i386.md (*3_doubleword): Mark
operand 0 as earlyclobber.

testsuite/ChangeLog:

2016-11-09  Uros Bizjak  

PR target/78262
* gcc.target/i386/pr78262.c: New test.

Bootstrapped and regression tested on x86_64-linux-gnu {,-m32}.

Committed to mainline, will be backported to release branches.

Uros.
Index: config/i386/i386.md
===
--- config/i386/i386.md (revision 242004)
+++ config/i386/i386.md (working copy)
@@ -10339,7 +10339,7 @@
   "operands[2] = gen_lowpart (QImode, operands[2]);")
 
 (define_insn_and_split "*3_doubleword"
-  [(set (match_operand:DWI 0 "register_operand" "=r")
+  [(set (match_operand:DWI 0 "register_operand" "=&r")
(any_shiftrt:DWI (match_operand:DWI 1 "register_operand" "0")
 (match_operand:QI 2 "nonmemory_operand" "c")))
(clobber (reg:CC FLAGS_REG))]
Index: testsuite/gcc.target/i386/pr78262.c
===
--- testsuite/gcc.target/i386/pr78262.c (nonexistent)
+++ testsuite/gcc.target/i386/pr78262.c (working copy)
@@ -0,0 +1,32 @@
+/* { dg-do run } */
+/* { dg-require-effective-target int128 } */
+/* { dg-options "-O -fschedule-insns" } */
+
+typedef unsigned char u8;
+typedef unsigned __int128 u128;
+
+static u128 u128_0;
+static u128 *p128;
+
+u128 __attribute__ ((noinline, noclone))
+foo(u8 u8_0)
+{
+  p128 = &u128_0;
+  u128_0 = u8_0;
+  u128_0 = u128_0 << 127 | u128_0 >> 1;
+  u128_0 >>= (u8)u128_0;
+  return 2 + u128_0;
+}
+
+int
+main()
+{
+  u128 x = foo(5);
+  if (p128 != &u128_0)
+__builtin_abort();
+  if (u128_0 != ((u128)2 << 124))
+__builtin_abort();
+  if (x != ((u128)2 << 124) + 2)
+__builtin_abort();
+  return 0;
+}