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 <ubiz...@gmail.com> PR target/78262 * config/i386/i386.md (*<shift_insn><mode>3_doubleword): Mark operand 0 as earlyclobber. testsuite/ChangeLog: 2016-11-09 Uros Bizjak <ubiz...@gmail.com> 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 "*<shift_insn><mode>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" "<S>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; +}