The following patch tightens the predicates of the peephole2 from my recent
"Integer min/max improvements patch" to only hoist clearing a register when
that register is a general register. Calling ix86_expand_clear with regs
other than GENERAL_REGS is not supported.
2020-08-12 Roger Sayle <roger@nextmovesoftware.com>
Uroš Bizjak <ubizjak@gmail.com>
gcc/ChangeLog
PR target/96558
* config/i386/i386.md (peephole2): Only reorder register clearing
instructions to allow use of xor for general registers.
gcc/testsuite/ChangeLog
PR target/96558
* gcc.dg/pr96558.c: New test.
;; i.e. prefer "xorl %eax,%eax; test/cmp" over "test/cmp; movl $0, %eax".
(define_peephole2
[(set (reg FLAGS_REG) (match_operand 0))
- (set (match_operand:SWI 1 "register_operand") (const_int 0))]
+ (set (match_operand:SWI 1 "general_reg_operand") (const_int 0))]
"peep2_regno_dead_p (0, FLAGS_REG)
&& !reg_overlap_mentioned_p (operands[1], operands[0])"
[(set (match_dup 2) (match_dup 0))]
--- /dev/null
+/* PR target/96558 */
+/* { dg-do compile { target int128 } } */
+/* { dg-options "-O2 -fno-expensive-optimizations -fno-gcse" } */
+
+int ky;
+long int h1;
+__int128 f1;
+
+int
+sd (void);
+
+int __attribute__ ((simd))
+i8 (void)
+{
+ __int128 vh;
+
+ if (sd () == 0)
+ h1 = 0;
+
+ do
+ {
+ long int lf = (long int) f1 ? h1 : 0;
+
+ ky += lf;
+ vh = lf | f1;
+ f1 = 1;
+ }
+ while (vh < (f1 ^ 2));
+
+ return 0;
+}
+