The following patch fixes a semi-latent bug for the HTM pattern used with
the __builtin_ttest() builtin.  This is supposed to expand to a tabortwci.
instruction which sets cr0 and then some code that copies the cr0 value
into a gpr and then shifts and masks it into the lowest 2 bits in the gpr.

With newish -mcpu targets, we generate a "mfocrf rX,128" to copy the cr0
value into bits 32-35 of the gpr.  However, in some cases, we will instead
generate a "mfcr rX" instruction, which copies all 8 CR fields into the
gpr, with cr0 again being in bits 32-35.  The difference is that the
mfocrf instruction seems to duplicate the 4-bit CR field in the gpr,
so bits 36-39 are a duplicate of bits 32-35.  The error in the ttest
pattern is that we only shift the value down 24 bits.  This "works"
when a mfocrf copied the cr0 into the rgeister due the duplicated CR
field, but is wrong when a mfcr instruction is used.

The following passed bootstrap and regtesting on powerpc64-linux.
Ok for trunk?  Is this also ok for the 4.9 and 4.8 branches once
my bootstraps and regtesting is done there?

Peter


gcc/
        * config/rs6000/htm.md (ttest): Use correct shift value to get CR0.

gcc/testsuite/
        * gcc.target/powerpc/htm-ttest.c: New test.

Index: gcc/config/rs6000/htm.md
===================================================================
--- gcc/config/rs6000/htm.md    (revision 210518)
+++ gcc/config/rs6000/htm.md    (working copy)
@@ -179,7 +179,7 @@ (define_expand "ttest"
                             (const_int 0)]
                            UNSPECV_HTM_TABORTWCI))
    (set (subreg:CC (match_dup 2) 0) (match_dup 1))
-   (set (match_dup 3) (lshiftrt:SI (match_dup 2) (const_int 24)))
+   (set (match_dup 3) (lshiftrt:SI (match_dup 2) (const_int 28)))
    (parallel [(set (match_operand:SI 0 "int_reg_operand" "")
                   (and:SI (match_dup 3) (const_int 15)))
               (clobber (scratch:CC))])]
Index: gcc/testsuite/gcc.target/powerpc/htm-ttest.c
===================================================================
--- gcc/testsuite/gcc.target/powerpc/htm-ttest.c        (revision 0)
+++ gcc/testsuite/gcc.target/powerpc/htm-ttest.c        (working copy)
@@ -0,0 +1,14 @@
+/* { dg-do compile { target { powerpc*-*-* } } } */
+/* { dg-skip-if "" { powerpc*-*-darwin* } { "*" } { "" } } */
+/* { dg-require-effective-target powerpc_htm_ok } */
+/* { dg-options "-O2 -mhtm" } */
+
+/* { dg-final { scan-assembler "rlwinm r?\[0-9\]+,r?\[0-9\]+,3,30,31" { target 
{ ilp32 } } } } */
+/* { dg-final { scan-assembler "rldicl r?\[0-9\]+,r?\[0-9\]+,35,62" { target { 
lp64 } } } } */
+
+#include <htmintrin.h>
+long
+ttest (void)
+{
+  return _HTM_STATE(__builtin_ttest());
+}


Reply via email to