S/390: Memory constraint cleanup

This fixes an issue with the long displacement memory address
constraints S and T.  These were defined to only accept long
displacement addresses.  This is wrong since a memory constraint must
not reject an address with a 0 displacement.  Reload relies on being
able to turn an invalid memory address into a valid one by reloading
the address into a base register.  The S and T constraints would
reject such an address.

This isn't really a problem for the backend since we used the
constraints with that knowledge there but it is a problem for people
writing inline assemblies.

gcc/ChangeLog:

2016-04-29  Ulrich Weigand  <uweigand@de.ibm.com>

	* config/s390/constraints.md ("U", "W"): Invoke
	s390_mem_constraint with "ZR" and "ZT".
	* config/s390/s390.c (s390_check_qrst_address): Reject invalid
	addresses when using LRA.  Accept also short displacements for S
	and T constraints.  Do not check for long displacement target for
	S and T constraints.
	(s390_mem_constraint): Remove handling of U and W constraints.
	* config/s390/s390.md (various patterns): Remove the short
	displacement constraints (Q and R) if a long displacement
	constraint is present.  Add longdisp as required CPU capability.
	* config/s390/vector.md: Likewise.
	* config/s390/vx-builtins.md: Likewise.

From-SVN: r235626
This commit is contained in:
Ulrich Weigand 2016-04-29 09:14:19 +00:00 committed by Andreas Krebbel
parent 849b265de1
commit 3e4be43f69
6 changed files with 274 additions and 230 deletions

View file

@ -1,3 +1,18 @@
2016-04-29 Ulrich Weigand <uweigand@de.ibm.com>
* config/s390/constraints.md ("U", "W"): Invoke
s390_mem_constraint with "ZR" and "ZT".
* config/s390/s390.c (s390_check_qrst_address): Reject invalid
addresses when using LRA. Accept also short displacements for S
and T constraints. Do not check for long displacement target for
S and T constraints.
(s390_mem_constraint): Remove handling of U and W constraints.
* config/s390/s390.md (various patterns): Remove the short
displacement constraints (Q and R) if a long displacement
constraint is present. Add longdisp as required CPU capability.
* config/s390/vector.md: Likewise.
* config/s390/vx-builtins.md: Likewise.
2016-04-29 Senthil Kumar Selvaraj <senthil_kumar.selvaraj@atmel.com>
PR target/60040

View file

@ -77,8 +77,8 @@
;; B -- Multiple letter constraint followed by Q, R, S, or T:
;; Memory reference of the type specified by second letter that
;; does *not* refer to a literal pool entry.
;; U -- Pointer with short displacement. (deprecated - use ZQZR)
;; W -- Pointer with long displacement. (deprecated - use ZSZT)
;; U -- Pointer with short displacement. (deprecated - use ZR)
;; W -- Pointer with long displacement. (deprecated - use ZT)
;; Y -- Address style operand without index.
;; ZQ -- Pointer without index register and with short displacement.
;; ZR -- Pointer with index register and short displacement.
@ -455,8 +455,7 @@
; the TARGET_MEM_CONSTRAINT macro.
(define_memory_constraint "m"
"Matches the most general memory address for pre-z10 machines."
(match_test "s390_mem_constraint (\"R\", op)
|| s390_mem_constraint (\"T\", op)"))
(match_test "s390_mem_constraint (\"T\", op)"))
(define_memory_constraint "AQ"
"@internal
@ -512,12 +511,12 @@
(define_address_constraint "U"
"Pointer with short displacement. (deprecated - use ZQZR)"
(match_test "s390_mem_constraint (\"U\", op)"))
"Pointer with short displacement. (deprecated - use ZR)"
(match_test "s390_mem_constraint (\"ZR\", op)"))
(define_address_constraint "W"
"Pointer with long displacement. (deprecated - use ZSZT)"
(match_test "s390_mem_constraint (\"W\", op)"))
"Pointer with long displacement. (deprecated - use ZT)"
(match_test "s390_mem_constraint (\"ZT\", op)"))
(define_address_constraint "ZQ"

View file

@ -3116,6 +3116,19 @@ s390_check_qrst_address (char c, rtx op, bool lit_pool_ok)
decomposed = true;
}
/* With reload, we sometimes get intermediate address forms that are
actually invalid as-is, but we need to accept them in the most
generic cases below ('R' or 'T'), since reload will in fact fix
them up. LRA behaves differently here; we never see such forms,
but on the other hand, we need to strictly reject every invalid
address form. Perform this check right up front. */
if (lra_in_progress)
{
if (!decomposed && !s390_decompose_address (op, &addr))
return 0;
decomposed = true;
}
switch (c)
{
case 'Q': /* no index short displacement */
@ -3140,25 +3153,17 @@ s390_check_qrst_address (char c, rtx op, bool lit_pool_ok)
break;
case 'S': /* no index long displacement */
if (!TARGET_LONG_DISPLACEMENT)
return 0;
if (!decomposed && !s390_decompose_address (op, &addr))
return 0;
if (addr.indx)
return 0;
if (s390_short_displacement (addr.disp))
return 0;
break;
case 'T': /* with index long displacement */
if (!TARGET_LONG_DISPLACEMENT)
return 0;
/* Any invalid address here will be fixed up by reload,
so accept it for the most generic constraint. */
if ((decomposed || s390_decompose_address (op, &addr))
&& s390_short_displacement (addr.disp))
return 0;
break;
default:
return 0;
}
@ -3167,7 +3172,7 @@ s390_check_qrst_address (char c, rtx op, bool lit_pool_ok)
/* Evaluates constraint strings described by the regular expression
([A|B|Z](Q|R|S|T))|U|W|Y and returns 1 if OP is a valid operand for
([A|B|Z](Q|R|S|T))|Y and returns 1 if OP is a valid operand for
the constraint given in STR, or 0 else. */
int
@ -3197,12 +3202,6 @@ s390_mem_constraint (const char *str, rtx op)
if (GET_CODE (op) != MEM)
return 0;
return s390_check_qrst_address (c, XEXP (op, 0), true);
case 'U':
return (s390_check_qrst_address ('Q', op, true)
|| s390_check_qrst_address ('R', op, true));
case 'W':
return (s390_check_qrst_address ('S', op, true)
|| s390_check_qrst_address ('T', op, true));
case 'Y':
/* Simply check for the basic form of a shift count. Reload will
take care of making sure we have a proper base register. */

File diff suppressed because it is too large Load diff

View file

@ -137,8 +137,8 @@
; Full HW vector size moves
(define_insn "mov<mode>"
[(set (match_operand:V_128 0 "nonimmediate_operand" "=v, v,QR, v, v, v, v, v,v,d")
(match_operand:V_128 1 "general_operand" " v,QR, v,j00,jm1,jyy,jxx,jKK,d,v"))]
[(set (match_operand:V_128 0 "nonimmediate_operand" "=v,v,R, v, v, v, v, v,v,d")
(match_operand:V_128 1 "general_operand" " v,R,v,j00,jm1,jyy,jxx,jKK,d,v"))]
"TARGET_VX"
"@
vlr\t%v0,%v1
@ -178,8 +178,8 @@
; However, this would probably be slower.
(define_insn "mov<mode>"
[(set (match_operand:V_8 0 "nonimmediate_operand" "=v,v,d, v,QR, v, v, v, v,d, Q, S, Q, S, d, d,d,d,d,R,T")
(match_operand:V_8 1 "general_operand" " v,d,v,QR, v,j00,jm1,jyy,jxx,d,j00,j00,jm1,jm1,j00,jm1,R,T,b,d,d"))]
[(set (match_operand:V_8 0 "nonimmediate_operand" "=v,v,d,v,R, v, v, v, v,d, Q, S, Q, S, d, d,d,d,d,R,T")
(match_operand:V_8 1 "general_operand" " v,d,v,R,v,j00,jm1,jyy,jxx,d,j00,j00,jm1,jm1,j00,jm1,R,T,b,d,d"))]
""
"@
vlr\t%v0,%v1
@ -206,8 +206,8 @@
[(set_attr "op_type" "VRR,VRS,VRS,VRX,VRX,VRI,VRI,VRI,VRI,RR,SI,SIY,SI,SIY,RI,RI,RX,RXY,RIL,RX,RXY")])
(define_insn "mov<mode>"
[(set (match_operand:V_16 0 "nonimmediate_operand" "=v,v,d, v,QR, v, v, v, v,d, Q, Q, d, d,d,d,d,R,T,b")
(match_operand:V_16 1 "general_operand" " v,d,v,QR, v,j00,jm1,jyy,jxx,d,j00,jm1,j00,jm1,R,T,b,d,d,d"))]
[(set (match_operand:V_16 0 "nonimmediate_operand" "=v,v,d,v,R, v, v, v, v,d, Q, Q, d, d,d,d,d,R,T,b")
(match_operand:V_16 1 "general_operand" " v,d,v,R,v,j00,jm1,jyy,jxx,d,j00,jm1,j00,jm1,R,T,b,d,d,d"))]
""
"@
vlr\t%v0,%v1
@ -233,8 +233,8 @@
[(set_attr "op_type" "VRR,VRS,VRS,VRX,VRX,VRI,VRI,VRI,VRI,RR,SIL,SIL,RI,RI,RX,RXY,RIL,RX,RXY,RIL")])
(define_insn "mov<mode>"
[(set (match_operand:V_32 0 "nonimmediate_operand" "=f,f,f,R,T,v,v,d, v,QR, f, v, v, v, v, Q, Q, d, d,d,d,d,d,R,T,b")
(match_operand:V_32 1 "general_operand" " f,R,T,f,f,v,d,v,QR, v,j00,j00,jm1,jyy,jxx,j00,jm1,j00,jm1,b,d,R,T,d,d,d"))]
[(set (match_operand:V_32 0 "nonimmediate_operand" "=f,f,f,R,T,v,v,d,v,R, f, v, v, v, v, Q, Q, d, d,d,d,d,d,R,T,b")
(match_operand:V_32 1 "general_operand" " f,R,T,f,f,v,d,v,R,v,j00,j00,jm1,jyy,jxx,j00,jm1,j00,jm1,b,d,R,T,d,d,d"))]
"TARGET_VX"
"@
lder\t%v0,%v1
@ -268,9 +268,9 @@
(define_insn "mov<mode>"
[(set (match_operand:V_64 0 "nonimmediate_operand"
"=f,f,f,R,T,v,v,d, v,QR, f, v, v, v, v, Q, Q, d, d,f,d,d,d, d,RT,b")
"=f,f,f,R,T,v,v,d,v,R, f, v, v, v, v, Q, Q, d, d,f,d,d,d,d,T,b")
(match_operand:V_64 1 "general_operand"
" f,R,T,f,f,v,d,v,QR, v,j00,j00,jm1,jyy,jxx,j00,jm1,j00,jm1,d,f,b,d,RT, d,d"))]
" f,R,T,f,f,v,d,v,R,v,j00,j00,jm1,jyy,jxx,j00,jm1,j00,jm1,d,f,b,d,T,d,d"))]
"TARGET_ZARCH"
"@
ldr\t%0,%1
@ -322,10 +322,10 @@
; up with vl vlvgg vst. Shouldn't the middle-end be able to handle
; that itself?
(define_insn "*vec_set<mode>"
[(set (match_operand:V 0 "register_operand" "=v, v,v")
(unspec:V [(match_operand:<non_vec> 1 "general_operand" "d,QR,K")
(match_operand:SI 2 "nonmemory_operand" "an, I,I")
(match_operand:V 3 "register_operand" "0, 0,0")]
[(set (match_operand:V 0 "register_operand" "=v,v,v")
(unspec:V [(match_operand:<non_vec> 1 "general_operand" "d,R,K")
(match_operand:SI 2 "nonmemory_operand" "an,I,I")
(match_operand:V 3 "register_operand" "0,0,0")]
UNSPEC_VEC_SET))]
"TARGET_VX
&& (!CONST_INT_P (operands[2])
@ -359,9 +359,9 @@
"TARGET_VX")
(define_insn "*vec_extract<mode>"
[(set (match_operand:<non_vec> 0 "nonimmediate_operand" "=d,QR")
(unspec:<non_vec> [(match_operand:V 1 "register_operand" "v, v")
(match_operand:SI 2 "nonmemory_operand" "an, I")]
[(set (match_operand:<non_vec> 0 "nonimmediate_operand" "=d,R")
(unspec:<non_vec> [(match_operand:V 1 "register_operand" "v,v")
(match_operand:SI 2 "nonmemory_operand" "an,I")]
UNSPEC_VEC_EXTRACT))]
"TARGET_VX
&& (!CONST_INT_P (operands[2])
@ -404,7 +404,7 @@
(define_insn "*vec_splats<mode>"
[(set (match_operand:V_HW 0 "register_operand" "=v,v,v,v")
(vec_duplicate:V_HW (match_operand:<non_vec> 1 "general_operand" "QR,K,v,d")))]
(vec_duplicate:V_HW (match_operand:<non_vec> 1 "general_operand" " R,K,v,d")))]
"TARGET_VX"
"@
vlrep<bhfgq>\t%v0,%1

View file

@ -70,7 +70,7 @@
[(set (match_operand:V_HW_32_64 0 "register_operand" "=v")
(unspec:V_HW_32_64 [(match_operand:V_HW_32_64 1 "register_operand" "0")
(match_operand:<tointvec> 2 "register_operand" "v")
(match_operand:BLK 3 "memory_operand" "QR")
(match_operand:BLK 3 "memory_operand" "R")
(match_operand:QI 4 "const_mask_operand" "C")]
UNSPEC_VEC_GATHER))]
"TARGET_VX && UINTVAL (operands[4]) < GET_MODE_NUNITS (<V_HW_32_64:MODE>mode)"
@ -170,7 +170,7 @@
(define_insn "vec_insert_and_zero<mode>"
[(set (match_operand:V_HW 0 "register_operand" "=v")
(unspec:V_HW [(match_operand:<non_vec> 1 "memory_operand" "QR")]
(unspec:V_HW [(match_operand:<non_vec> 1 "memory_operand" "R")]
UNSPEC_VEC_INSERT_AND_ZERO))]
"TARGET_VX"
"vllez<bhfgq>\t%v0,%1"
@ -178,7 +178,7 @@
(define_insn "vlbb"
[(set (match_operand:V16QI 0 "register_operand" "=v")
(unspec:V16QI [(match_operand:BLK 1 "memory_operand" "QR")
(unspec:V16QI [(match_operand:BLK 1 "memory_operand" "R")
(match_operand:QI 2 "const_mask_operand" "C")]
UNSPEC_VEC_LOAD_BNDRY))]
"TARGET_VX && UINTVAL (operands[2]) < 7"