Hi!

rs6000.md has 2 sets of patterns for and with comparison, the non-_mask
ones have !rs6000_is_valid_and_mask (operands[2], <MODE>mode) predicate
and have an extra clobber for the case where the destination is not first
cc reg, while the second set implicitly assumes the operand is a valid
mask operand, don't have that extra clobber and split into and form
that doesn't clobber the first cc reg.  Unfortunately that implicit
assumption doesn't hold when e.g. IRA creates such insn (replaces a pseudo
with a const_int); then we match even when the operand isn't valid mask
but split into something that requires it.

Fixed thusly, Segher has kindly bootstrapped/regtest it on powerpc* and
pre-approved on IRC.  Committed to trunk.

2016-12-09  Jakub Jelinek  <ja...@redhat.com>

        PR target/72742
        * config/rs6000/rs6000.md (*and<mode>3_imm_mask_dot,
        *and<mode>3_imm_mask_dot2): Add rs6000_is_valid_and_mask to insn
        condition.

        * gcc.c-torture/compile/pr72742.c: New test.

--- gcc/config/rs6000/rs6000.md.jj      2016-12-07 10:11:32.000000000 +0100
+++ gcc/config/rs6000/rs6000.md 2016-12-09 16:30:50.604370286 +0100
@@ -3254,7 +3254,8 @@ (define_insn_and_split "*and<mode>3_imm_
                    (const_int 0)))
    (clobber (match_scratch:GPR 0 "=r,r"))]
   "(<MODE>mode == Pmode || UINTVAL (operands[2]) <= 0x7fffffff)
-   && rs6000_gen_cell_microcode"
+   && rs6000_gen_cell_microcode
+   && rs6000_is_valid_and_mask (operands[2], <MODE>mode)"
   "@
    andi%e2. %0,%1,%u2
    #"
@@ -3279,7 +3280,8 @@ (define_insn_and_split "*and<mode>3_imm_
        (and:GPR (match_dup 1)
                 (match_dup 2)))]
   "(<MODE>mode == Pmode || UINTVAL (operands[2]) <= 0x7fffffff)
-   && rs6000_gen_cell_microcode"
+   && rs6000_gen_cell_microcode
+   && rs6000_is_valid_and_mask (operands[2], <MODE>mode)"
   "@
    andi%e2. %0,%1,%u2
    #"
--- gcc/testsuite/gcc.c-torture/compile/pr72742.c.jj    2016-12-09 
16:39:10.327036689 +0100
+++ gcc/testsuite/gcc.c-torture/compile/pr72742.c       2016-12-09 
16:38:57.000000000 +0100
@@ -0,0 +1,79 @@
+/* PR target/72742 */
+
+int a, b;
+unsigned short int c;
+
+void
+foo (int x, unsigned short int *y)
+{
+  int fx;
+ lab:
+    {
+      unsigned short int va;
+      if (x != 0)
+       {
+         c %= a < 0;
+         while (c < 17)
+           ++c;
+         b &= fx;
+         if ((a & (b != 0 ? *y : 0)) != 0)
+           {
+             va /= 3;
+             a += (va != 0) ? (va = a) : 0;
+           }
+         a = va && a;
+         goto lab;
+         y = &va;
+       }
+    }
+}
+
+void
+bar (int x, unsigned short int *y)
+{
+  int fx;
+ lab:
+    {
+      unsigned short int va;
+      if (x != 0)
+       {
+         c %= a < 0;
+         while (c < 17)
+           ++c;
+         b &= fx;
+         if ((a & (b != 0 ? *y : 24)) != 0)
+           {
+             va /= 3;
+             a += (va != 0) ? (va = a) : 0;
+           }
+         a = va && a;
+         goto lab;
+         y = &va;
+       }
+    }
+}
+
+void
+baz (int x, unsigned short int *y)
+{
+  int fx;
+ lab:
+    {
+      unsigned short int va;
+      if (x != 0)
+       {
+         c %= a < 0;
+         while (c < 17)
+           ++c;
+         b &= fx;
+         if ((a & (b != 0 ? *y : 25)) != 0)
+           {
+             va /= 3;
+             a += (va != 0) ? (va = a) : 0;
+           }
+         a = va && a;
+         goto lab;
+         y = &va;
+       }
+    }
+}

        Jakub

Reply via email to