===================================================================
@@ -108,7 +108,7 @@
power6-store-update-indexed,\
power6-fpstore,\
power6-fpstore-update"
- "store_data_bypass_p")
+ "rs6000_store_data_bypass_p")
(define_insn_reservation "power6-load-ext" 4 ; fx
(and (eq_attr "type" "load")
@@ -128,7 +128,7 @@
power6-store-update-indexed,\
power6-fpstore,\
power6-fpstore-update"
- "store_data_bypass_p")
+ "rs6000_store_data_bypass_p")
(define_insn_reservation "power6-load-update" 2 ; fx
(and (eq_attr "type" "load")
@@ -276,7 +276,7 @@
power6-store-update-indexed,\
power6-fpstore,\
power6-fpstore-update"
- "store_data_bypass_p")
+ "rs6000_store_data_bypass_p")
(define_insn_reservation "power6-cntlz" 2
(and (eq_attr "type" "cntlz")
@@ -289,7 +289,7 @@
power6-store-update-indexed,\
power6-fpstore,\
power6-fpstore-update"
- "store_data_bypass_p")
+ "rs6000_store_data_bypass_p")
(define_insn_reservation "power6-var-rotate" 4
(and (eq_attr "type" "shift")
@@ -355,7 +355,7 @@
power6-store-update-indexed,\
power6-fpstore,\
power6-fpstore-update"
- "store_data_bypass_p")
+ "rs6000_store_data_bypass_p")
(define_insn_reservation "power6-delayed-compare" 2 ; N/A
(and (eq_attr "type" "shift")
@@ -420,7 +420,7 @@
power6-store-update-indexed,\
power6-fpstore,\
power6-fpstore-update"
- "store_data_bypass_p")
+ "rs6000_store_data_bypass_p")
(define_insn_reservation "power6-idiv" 44
(and (eq_attr "type" "div")
@@ -436,7 +436,7 @@
; power6-store-update-indexed,\
; power6-fpstore,\
; power6-fpstore-update"
-; "store_data_bypass_p")
+; "rs6000_store_data_bypass_p")
(define_insn_reservation "power6-ldiv" 56
(and (eq_attr "type" "div")
@@ -452,7 +452,7 @@
; power6-store-update-indexed,\
; power6-fpstore,\
; power6-fpstore-update"
-; "store_data_bypass_p")
+; "rs6000_store_data_bypass_p")
(define_insn_reservation "power6-mtjmpr" 2
(and (eq_attr "type" "mtjmpr,mfjmpr")
@@ -510,7 +510,7 @@
(define_bypass 1 "power6-fp"
"power6-fpstore,power6-fpstore-update"
- "store_data_bypass_p")
+ "rs6000_store_data_bypass_p")
(define_insn_reservation "power6-fpcompare" 8
(and (eq_attr "type" "fpcompare")
===================================================================
@@ -226,6 +226,7 @@ extern void rs6000_aix_asm_output_dwarf_table_ref
extern void get_ppc476_thunk_name (char name[32]);
extern bool rs6000_overloaded_builtin_p (enum rs6000_builtins);
extern const char *rs6000_overloaded_builtin_name (enum rs6000_builtins);
+extern int rs6000_store_data_bypass_p (rtx_insn *, rtx_insn *);
extern HOST_WIDE_INT rs6000_builtin_mask_calculate (void);
extern void rs6000_asm_output_dwarf_pcrel (FILE *file, int size,
const char *label);
===================================================================
@@ -508,6 +508,91 @@ mode_supports_pre_modify_p (machine_mode mode)
!= 0);
}
+/* Given that there exists at least one variable that is set (produced)
+ by OUT_INSN and read (consumed) by IN_INSN, return true iff
+ IN_INSN represents one or more memory store operations and none of
+ the variables set by OUT_INSN is used by IN_INSN as the address of a
+ store operation. If either IN_INSN or OUT_INSN does not represent
+ a "single" RTL SET expression (as loosely defined by the
+ implementation of the single_set function) or a PARALLEL with only
+ SETs, CLOBBERs, and USEs inside, this function returns false.
+
+ This rs6000-specific version of store_data_bypass_p checks for
+ certain conditions that result in assertion failures (and internal
+ compiler errors) in the generic store_data_bypass_p function and
+ returns false rather than calling store_data_bypass_p if one of the
+ problematic conditions is detected. */
+
+int
+rs6000_store_data_bypass_p (rtx_insn *out_insn, rtx_insn *in_insn)
+{
+ rtx out_set, in_set;
+ rtx out_pat, in_pat;
+ rtx out_exp, in_exp;
+ int i, j;
+
+ in_set = single_set (in_insn);
+ if (in_set)
+ {
+ if (MEM_P (SET_DEST (in_set)))
+ {
+ out_set = single_set (out_insn);
+ if (!out_set)
+ {
+ out_pat = PATTERN (out_insn);
+ if (GET_CODE (out_pat) == PARALLEL)
+ {
+ for (i = 0; i < XVECLEN (out_pat, 0); i++)
+ {
+ out_exp = XVECEXP (out_pat, 0, i);
+ if ((GET_CODE (out_exp) == CLOBBER)
+ || (GET_CODE (out_exp) == USE))
+ continue;
+ else if (GET_CODE (out_exp) != SET)
+ return false;
+ }
+ }
+ }
+ }
+ }
+ else
+ {
+ in_pat = PATTERN (in_insn);
+ if (GET_CODE (in_pat) != PARALLEL)
+ return false;
+
+ for (i = 0; i < XVECLEN (in_pat, 0); i++)
+ {
+ in_exp = XVECEXP (in_pat, 0, i);
+ if ((GET_CODE (in_exp) == CLOBBER) || (GET_CODE (in_exp) == USE))
+ continue;
+ else if (GET_CODE (in_exp) != SET)
+ return false;
+
+ if (MEM_P (SET_DEST (in_exp)))
+ {
+ out_set = single_set (out_insn);
+ if (!out_set)
+ {
+ out_pat = PATTERN (out_insn);
+ if (GET_CODE (out_pat) != PARALLEL)
+ return false;
+ for (j = 0; j < XVECLEN (out_pat, 0); j++)
+ {
+ out_exp = XVECEXP (out_pat, 0, j);
+ if ((GET_CODE (out_exp) == CLOBBER)
+ || (GET_CODE (out_exp) == USE))
+ continue;
+ else if (GET_CODE (out_exp) != SET)
+ return false;
+ }
+ }
+ }
+ }
+ }
+ return store_data_bypass_p (out_insn, in_insn);
+}
+
/* Return true if we have D-form addressing in altivec registers. */
static inline bool
mode_supports_vmx_dform (machine_mode mode)
@@ -32999,7 +33084,7 @@ rs6000_adjust_cost (rtx_insn *insn, int dep_type,
case TYPE_LOAD:
case TYPE_CNTLZ:
{
- if (! store_data_bypass_p (dep_insn, insn))
+ if (! rs6000_store_data_bypass_p (dep_insn, insn))
return get_attr_sign_extend (dep_insn)
== SIGN_EXTEND_YES ? 6 : 4;
break;
@@ -33006,7 +33091,7 @@ rs6000_adjust_cost (rtx_insn *insn, int dep_type,
}
case TYPE_SHIFT:
{
- if (! store_data_bypass_p (dep_insn, insn))
+ if (! rs6000_store_data_bypass_p (dep_insn, insn))
return get_attr_var_shift (dep_insn) == VAR_SHIFT_YES ?
6 : 3;
break;
@@ -33017,7 +33102,7 @@ rs6000_adjust_cost (rtx_insn *insn, int dep_type,
case TYPE_EXTS:
case TYPE_INSERT:
{
- if (! store_data_bypass_p (dep_insn, insn))
+ if (! rs6000_store_data_bypass_p (dep_insn, insn))
return 3;
break;
}
@@ -33026,19 +33111,19 @@ rs6000_adjust_cost (rtx_insn *insn, int dep_type,
case TYPE_FPSTORE:
{
if (get_attr_update (dep_insn) == UPDATE_YES
- && ! store_data_bypass_p (dep_insn, insn))
+ && ! rs6000_store_data_bypass_p (dep_insn, insn))
return 3;
break;
}
case TYPE_MUL:
{
- if (! store_data_bypass_p (dep_insn, insn))
+ if (! rs6000_store_data_bypass_p (dep_insn, insn))
return 17;
break;
}
case TYPE_DIV:
{
- if (! store_data_bypass_p (dep_insn, insn))
+ if (! rs6000_store_data_bypass_p (dep_insn, insn))
return get_attr_size (dep_insn) == SIZE_32 ? 45 : 57;
break;
}
===================================================================
@@ -0,0 +1,22 @@
+/* { dg-do compile { target { powerpc*-*-* } } } */
+/* { dg-skip-if "do not override -mcpu" { powerpc*-*-* } { "-mcpu=*" } { "-mcpu=power6" } } */
+/* { dg-require-effective-target dfp_hw } */
+/* { dg-options "-mcpu=power6 -mno-sched-epilog -Ofast" } */
+
+/* Prior to resolving PR 80101, this test case resulted in an internal
+ compiler error. The role of this test program is to assure that
+ dejagnu's "test for excess errors" does not find any. */
+
+int b;
+
+void e ();
+
+int c ()
+{
+ struct
+ {
+ int a[b];
+ } d;
+ if (d.a[0])
+ e ();
+}