* [RS6000] PR72802 part 1, fix constraints for lxssp/stxssp
@ 2016-08-05 2:05 Alan Modra
2016-08-05 22:38 ` Segher Boessenkool
2016-08-09 5:48 ` Alan Modra
0 siblings, 2 replies; 3+ messages in thread
From: Alan Modra @ 2016-08-05 2:05 UTC (permalink / raw)
To: gcc-patches; +Cc: Segher Boessenkool
We can't use "o" constraint for lsxxp/stxssp since those insns have a
DS-form offset field, ie. the bottom two bits of the offset must be 0.
So use "wY" instead, but that leads to finding another problem..
mem_operand_gpr is only suitable for gpr loads/stores since it does
not enforce multiple-of-4 offsets when -m32. So "wY" can't use
mem_operand_gpr, and the vsx tests in mem_operand_gpr are bogus.
I've deleted offsettable_mem_14bit_operand because it wasn't used
anywhere but in the wY constraint. Note also that the new wY
constraint doesn't use memory_operand because that is redundant in a
constraint, having already been tested in the predicate.
Boostrapped and regression tested powerpc64le-linux and
powerpc64-linux. This doesn't completely fix the pr due to hitting
another reload problem, so the testcase is in part 2.
PR target/72802
* config/rs6000/rs6000.c (mem_operand_gpr): Remove vsx dform test.
(mem_operand_ds_form): New predicate.
* config/rs6000/rs6000-protos.h (mem_operand_ds_form): Declare.
* config/rs6000/constraints.md (wY): Use mem_operand_df_form.
* config/rs6000/predicates.md (offsettable_mem_14bit_operand): Delete.
* config/rs6000/rs6000.md (f32_lm2, f32_sm2): Use wY for SF.
(extendsfdf2_fpr): Replace o constraint with wY.
diff --git a/gcc/config/rs6000/constraints.md b/gcc/config/rs6000/constraints.md
index 1871325..7535c35 100644
--- a/gcc/config/rs6000/constraints.md
+++ b/gcc/config/rs6000/constraints.md
@@ -185,10 +185,14 @@
"Vector constant that can be loaded with XXSPLTIB & sign extension."
(match_test "xxspltib_constant_split (op, mode)"))
-;; ISA 3.0 D-form instruction that has the bottom 2 bits 0 (LXSD or STXSD).
+;; ISA 3.0 DS-form instruction that has the bottom 2 bits 0 and no update form.
+;; Used by LXSD/STXSD/LXSSP/STXSSP. In contrast to "Y", the multiple-of-four
+;; offset is enforced for 32-bit too.
(define_memory_constraint "wY"
"Offsettable memory operand, with bottom 2 bits 0"
- (match_operand 0 "offsettable_mem_14bit_operand"))
+ (and (match_code "mem")
+ (not (match_test "update_address_mem (op, mode)"))
+ (match_test "mem_operand_ds_form (op, mode)")))
;; Altivec style load/store that ignores the bottom bits of the address
(define_memory_constraint "wZ"
diff --git a/gcc/config/rs6000/predicates.md b/gcc/config/rs6000/predicates.md
index 0d10e9a..6436d5e 100644
--- a/gcc/config/rs6000/predicates.md
+++ b/gcc/config/rs6000/predicates.md
@@ -734,15 +734,6 @@
(and (match_operand 0 "memory_operand")
(match_test "offsettable_nonstrict_memref_p (op)")))
-;; Return 1 if the operand is an offsettable memory operand for ISA 3.0
-;; scalar LXSD/STXSD that must have the bottom 2 bits 0 and no update
-;; form
-(define_predicate "offsettable_mem_14bit_operand"
- (and (match_operand 0 "memory_operand")
- (match_test "offsettable_nonstrict_memref_p (op)")
- (match_test "mem_operand_gpr (op, mode)")
- (not (match_test "update_address_mem (op, mode)"))))
-
;; Return 1 if the operand is suitable for load/store quad memory.
;; This predicate only checks for non-atomic loads/stores (not lqarx/stqcx).
(define_predicate "quad_memory_operand"
diff --git a/gcc/config/rs6000/rs6000-protos.h b/gcc/config/rs6000/rs6000-protos.h
index 8a307a8..c7e338a 100644
--- a/gcc/config/rs6000/rs6000-protos.h
+++ b/gcc/config/rs6000/rs6000-protos.h
@@ -39,6 +39,7 @@ extern int num_insns_constant (rtx, machine_mode);
extern int num_insns_constant_wide (HOST_WIDE_INT);
extern int small_data_operand (rtx, machine_mode);
extern bool mem_operand_gpr (rtx, machine_mode);
+extern bool mem_operand_ds_form (rtx, machine_mode);
extern bool toc_relative_expr_p (const_rtx, bool);
extern bool invalid_e500_subreg (rtx, machine_mode);
extern void validate_condition_mode (enum rtx_code, machine_mode);
diff --git a/gcc/config/rs6000/rs6000.c b/gcc/config/rs6000/rs6000.c
index 779ba1f..c59d07a 100644
--- a/gcc/config/rs6000/rs6000.c
+++ b/gcc/config/rs6000/rs6000.c
@@ -7717,8 +7717,34 @@ mem_operand_gpr (rtx op, machine_mode mode)
if (TARGET_POWERPC64 && (offset & 3) != 0)
return false;
- if (mode_supports_vsx_dform_quad (mode)
- && !quad_address_offset_p (offset))
+ extra = GET_MODE_SIZE (mode) - UNITS_PER_WORD;
+ if (extra < 0)
+ extra = 0;
+
+ if (GET_CODE (addr) == LO_SUM)
+ /* For lo_sum addresses, we must allow any offset except one that
+ causes a wrap, so test only the low 16 bits. */
+ offset = ((offset & 0xffff) ^ 0x8000) - 0x8000;
+
+ return offset + 0x8000 < 0x10000u - extra;
+}
+
+/* As above, but for DS-FORM VSX insns. Unlike mem_operand_gpr,
+ enforce an offset divisible by 4 even for 32-bit. */
+
+bool
+mem_operand_ds_form (rtx op, machine_mode mode)
+{
+ unsigned HOST_WIDE_INT offset;
+ int extra;
+ rtx addr = XEXP (op, 0);
+
+ op = address_offset (addr);
+ if (op == NULL_RTX)
+ return true;
+
+ offset = INTVAL (op);
+ if ((offset & 3) != 0)
return false;
extra = GET_MODE_SIZE (mode) - UNITS_PER_WORD;
diff --git a/gcc/config/rs6000/rs6000.md b/gcc/config/rs6000/rs6000.md
index 45ad661..f4c00d2 100644
--- a/gcc/config/rs6000/rs6000.md
+++ b/gcc/config/rs6000/rs6000.md
@@ -446,7 +446,7 @@
(define_mode_attr f32_lr [(SF "f") (SD "wz")])
(define_mode_attr f32_lr2 [(SF "wb") (SD "wn")])
(define_mode_attr f32_lm [(SF "m") (SD "Z")])
-(define_mode_attr f32_lm2 [(SF "o") (SD "wn")])
+(define_mode_attr f32_lm2 [(SF "wY") (SD "wn")])
(define_mode_attr f32_li [(SF "lfs%U1%X1 %0,%1") (SD "lfiwzx %0,%y1")])
(define_mode_attr f32_li2 [(SF "lxssp %0,%1") (SD "lfiwzx %0,%y1")])
(define_mode_attr f32_lv [(SF "lxsspx %x0,%y1") (SD "lxsiwzx %x0,%y1")])
@@ -455,7 +455,7 @@
(define_mode_attr f32_sr [(SF "f") (SD "wx")])
(define_mode_attr f32_sr2 [(SF "wb") (SD "wn")])
(define_mode_attr f32_sm [(SF "m") (SD "Z")])
-(define_mode_attr f32_sm2 [(SF "o") (SD "wn")])
+(define_mode_attr f32_sm2 [(SF "wY") (SD "wn")])
(define_mode_attr f32_si [(SF "stfs%U0%X0 %1,%0") (SD "stfiwx %1,%y0")])
(define_mode_attr f32_si2 [(SF "stxssp %1,%0") (SD "stfiwx %1,%y0")])
(define_mode_attr f32_sv [(SF "stxsspx %x1,%y0") (SD "stxsiwzx %x1,%y0")])
@@ -4538,7 +4538,7 @@
(define_insn_and_split "*extendsfdf2_fpr"
[(set (match_operand:DF 0 "gpc_reg_operand" "=d,?d,d,ws,?ws,wu,wb")
- (float_extend:DF (match_operand:SF 1 "reg_or_mem_operand" "0,f,m,0,wy,Z,o")))]
+ (float_extend:DF (match_operand:SF 1 "reg_or_mem_operand" "0,f,m,0,wy,Z,wY")))]
"TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT"
"@
#
--
Alan Modra
Australia Development Lab, IBM
^ permalink raw reply [flat|nested] 3+ messages in thread
* Re: [RS6000] PR72802 part 1, fix constraints for lxssp/stxssp
2016-08-05 2:05 [RS6000] PR72802 part 1, fix constraints for lxssp/stxssp Alan Modra
@ 2016-08-05 22:38 ` Segher Boessenkool
2016-08-09 5:48 ` Alan Modra
1 sibling, 0 replies; 3+ messages in thread
From: Segher Boessenkool @ 2016-08-05 22:38 UTC (permalink / raw)
To: Alan Modra; +Cc: gcc-patches
On Fri, Aug 05, 2016 at 11:35:11AM +0930, Alan Modra wrote:
> diff --git a/gcc/config/rs6000/rs6000.c b/gcc/config/rs6000/rs6000.c
> index 779ba1f..c59d07a 100644
> --- a/gcc/config/rs6000/rs6000.c
> +++ b/gcc/config/rs6000/rs6000.c
> @@ -7717,8 +7717,34 @@ mem_operand_gpr (rtx op, machine_mode mode)
> if (TARGET_POWERPC64 && (offset & 3) != 0)
> return false;
>
> - if (mode_supports_vsx_dform_quad (mode)
> - && !quad_address_offset_p (offset))
> + extra = GET_MODE_SIZE (mode) - UNITS_PER_WORD;
> + if (extra < 0)
> + extra = 0;
> +
> + if (GET_CODE (addr) == LO_SUM)
> + /* For lo_sum addresses, we must allow any offset except one that
> + causes a wrap, so test only the low 16 bits. */
> + offset = ((offset & 0xffff) ^ 0x8000) - 0x8000;
You could use sext_hwi instead? offset = sext_hwi (offset, 16);
There are many other explicit manipulations in the code already of course,
just FYI.
This seems like an improvement; okay for trunk, thanks. I don't think
we're there yet though, there is more wrong / suboptimal than just the
PR :-/
Segher
^ permalink raw reply [flat|nested] 3+ messages in thread
* Re: [RS6000] PR72802 part 1, fix constraints for lxssp/stxssp
2016-08-05 2:05 [RS6000] PR72802 part 1, fix constraints for lxssp/stxssp Alan Modra
2016-08-05 22:38 ` Segher Boessenkool
@ 2016-08-09 5:48 ` Alan Modra
1 sibling, 0 replies; 3+ messages in thread
From: Alan Modra @ 2016-08-09 5:48 UTC (permalink / raw)
To: gcc-patches; +Cc: Segher Boessenkool
Now backported to gcc-6-branch too, after bootstrap and regression
testing.
PR target/72802
* config/rs6000/rs6000.c (mem_operand_gpr): Remove vsx dform test.
(mem_operand_ds_form): New predicate.
* config/rs6000/rs6000-protos.h (mem_operand_ds_form): Declare.
* config/rs6000/constraints.md (wY): New constraint.
* config/rs6000/rs6000.md (f32_lm2, f32_sm2): Use wY for SF.
(extendsfdf2_fpr): Replace o constraint with wY.
diff --git a/gcc/config/rs6000/constraints.md b/gcc/config/rs6000/constraints.md
index ef8f617..465ad6d 100644
--- a/gcc/config/rs6000/constraints.md
+++ b/gcc/config/rs6000/constraints.md
@@ -180,6 +180,15 @@
"Vector constant that can be loaded with XXSPLTIB & sign extension."
(match_test "xxspltib_constant_split (op, mode)"))
+;; ISA 3.0 DS-form instruction that has the bottom 2 bits 0 and no update form.
+;; Used by LXSD/STXSD/LXSSP/STXSSP. In contrast to "Y", the multiple-of-four
+;; offset is enforced for 32-bit too.
+(define_memory_constraint "wY"
+ "Offsettable memory operand, with bottom 2 bits 0"
+ (and (match_code "mem")
+ (not (match_test "update_address_mem (op, mode)"))
+ (match_test "mem_operand_ds_form (op, mode)")))
+
;; Altivec style load/store that ignores the bottom bits of the address
(define_memory_constraint "wZ"
"Indexed or indirect memory operand, ignoring the bottom 4 bits"
diff --git a/gcc/config/rs6000/rs6000-protos.h b/gcc/config/rs6000/rs6000-protos.h
index 0a47075..3bb25c0 100644
--- a/gcc/config/rs6000/rs6000-protos.h
+++ b/gcc/config/rs6000/rs6000-protos.h
@@ -39,6 +39,7 @@ extern int num_insns_constant (rtx, machine_mode);
extern int num_insns_constant_wide (HOST_WIDE_INT);
extern int small_data_operand (rtx, machine_mode);
extern bool mem_operand_gpr (rtx, machine_mode);
+extern bool mem_operand_ds_form (rtx, machine_mode);
extern bool toc_relative_expr_p (const_rtx, bool);
extern bool invalid_e500_subreg (rtx, machine_mode);
extern void validate_condition_mode (enum rtx_code, machine_mode);
diff --git a/gcc/config/rs6000/rs6000.c b/gcc/config/rs6000/rs6000.c
index 67c2f53..54ee990 100644
--- a/gcc/config/rs6000/rs6000.c
+++ b/gcc/config/rs6000/rs6000.c
@@ -7309,8 +7309,34 @@ mem_operand_gpr (rtx op, machine_mode mode)
if (TARGET_POWERPC64 && (offset & 3) != 0)
return false;
- if (mode_supports_vsx_dform_quad (mode)
- && !quad_address_offset_p (offset))
+ extra = GET_MODE_SIZE (mode) - UNITS_PER_WORD;
+ if (extra < 0)
+ extra = 0;
+
+ if (GET_CODE (addr) == LO_SUM)
+ /* For lo_sum addresses, we must allow any offset except one that
+ causes a wrap, so test only the low 16 bits. */
+ offset = ((offset & 0xffff) ^ 0x8000) - 0x8000;
+
+ return offset + 0x8000 < 0x10000u - extra;
+}
+
+/* As above, but for DS-FORM VSX insns. Unlike mem_operand_gpr,
+ enforce an offset divisible by 4 even for 32-bit. */
+
+bool
+mem_operand_ds_form (rtx op, machine_mode mode)
+{
+ unsigned HOST_WIDE_INT offset;
+ int extra;
+ rtx addr = XEXP (op, 0);
+
+ op = address_offset (addr);
+ if (op == NULL_RTX)
+ return true;
+
+ offset = INTVAL (op);
+ if ((offset & 3) != 0)
return false;
extra = GET_MODE_SIZE (mode) - UNITS_PER_WORD;
diff --git a/gcc/config/rs6000/rs6000.md b/gcc/config/rs6000/rs6000.md
index ab9202e..ffcefe4 100644
--- a/gcc/config/rs6000/rs6000.md
+++ b/gcc/config/rs6000/rs6000.md
@@ -446,7 +446,7 @@
(define_mode_attr f32_lr [(SF "f") (SD "wz")])
(define_mode_attr f32_lr2 [(SF "wb") (SD "wn")])
(define_mode_attr f32_lm [(SF "m") (SD "Z")])
-(define_mode_attr f32_lm2 [(SF "o") (SD "wn")])
+(define_mode_attr f32_lm2 [(SF "wY") (SD "wn")])
(define_mode_attr f32_li [(SF "lfs%U1%X1 %0,%1") (SD "lfiwzx %0,%y1")])
(define_mode_attr f32_li2 [(SF "lxssp %0,%1") (SD "lfiwzx %0,%y1")])
(define_mode_attr f32_lv [(SF "lxsspx %x0,%y1") (SD "lxsiwzx %x0,%y1")])
@@ -455,7 +455,7 @@
(define_mode_attr f32_sr [(SF "f") (SD "wx")])
(define_mode_attr f32_sr2 [(SF "wb") (SD "wn")])
(define_mode_attr f32_sm [(SF "m") (SD "Z")])
-(define_mode_attr f32_sm2 [(SF "o") (SD "wn")])
+(define_mode_attr f32_sm2 [(SF "wY") (SD "wn")])
(define_mode_attr f32_si [(SF "stfs%U0%X0 %1,%0") (SD "stfiwx %1,%y0")])
(define_mode_attr f32_si2 [(SF "stxssp %1,%0") (SD "stfiwx %1,%y0")])
(define_mode_attr f32_sv [(SF "stxsspx %x1,%y0") (SD "stxsiwzx %x1,%y0")])
@@ -4504,7 +4504,7 @@
(define_insn_and_split "*extendsfdf2_fpr"
[(set (match_operand:DF 0 "gpc_reg_operand" "=d,?d,d,ws,?ws,wu,wb")
- (float_extend:DF (match_operand:SF 1 "reg_or_mem_operand" "0,f,m,0,wy,Z,o")))]
+ (float_extend:DF (match_operand:SF 1 "reg_or_mem_operand" "0,f,m,0,wy,Z,wY")))]
"TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT"
"@
#
--
Alan Modra
Australia Development Lab, IBM
^ permalink raw reply [flat|nested] 3+ messages in thread
end of thread, other threads:[~2016-08-09 5:48 UTC | newest]
Thread overview: 3+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2016-08-05 2:05 [RS6000] PR72802 part 1, fix constraints for lxssp/stxssp Alan Modra
2016-08-05 22:38 ` Segher Boessenkool
2016-08-09 5:48 ` Alan Modra
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).