@@ -145,20 +145,11 @@
;; Return true if OP a valid operand for the LARL instruction.
(define_predicate "larl_operand"
- (match_code "label_ref, symbol_ref, const")
+ (match_code "label_ref, symbol_ref, const, plus, unspec")
{
- /* Allow labels and local symbols. */
- if (GET_CODE (op) == LABEL_REF)
- return true;
- if (SYMBOL_REF_P (op))
- return (!SYMBOL_FLAG_NOTALIGN2_P (op)
- && SYMBOL_REF_TLS_MODEL (op) == 0
- && s390_rel_address_ok_p (op));
-
- /* Everything else must have a CONST, so strip it. */
- if (GET_CODE (op) != CONST)
- return false;
- op = XEXP (op, 0);
+ /* Strip CONST to unify SYMBOL_REF and UNSPEC_LTREF handling. */
+ if (GET_CODE (op) == CONST)
+ op = XEXP (op, 0);
/* Allow adding *even* in-range constants. */
if (GET_CODE (op) == PLUS)
@@ -172,9 +163,11 @@
op = XEXP (op, 0);
}
- /* Labels and local symbols allowed here as well. */
+ /* Allow labels and local symbols. */
if (GET_CODE (op) == LABEL_REF)
return true;
+ if (GET_CODE (op) == UNSPEC && XINT (op, 1) == UNSPEC_LTREF)
+ op = XVECEXP (op, 0, 0);
if (SYMBOL_REF_P (op))
return (!SYMBOL_FLAG_NOTALIGN2_P (op)
&& SYMBOL_REF_TLS_MODEL (op) == 0
@@ -3019,8 +3019,9 @@ s390_decompose_address (rtx addr, struct s390_address *out)
orig_disp = gen_rtx_CONST (Pmode, disp);
if (offset)
{
- /* If we have an offset, make sure it does not
- exceed the size of the constant pool entry. */
+ /* If we have an offset, make sure it does not exceed the size of
+ the constant pool entry. Otherwise we might generate an
+ out-of-range displacement for the base register form. */
rtx sym = XVECEXP (disp, 0, 0);
if (offset >= GET_MODE_SIZE (get_pool_mode (sym)))
return false;
@@ -3140,6 +3141,9 @@ s390_loadrelative_operand_p (rtx addr, rtx *symref, HOST_WIDE_INT *addend)
addr = XEXP (addr, 0);
}
+ if (GET_CODE (addr) == UNSPEC && XINT (addr, 1) == UNSPEC_LTREF)
+ addr = XVECEXP (addr, 0, 0);
+
if (GET_CODE (addr) == SYMBOL_REF
|| (GET_CODE (addr) == UNSPEC
&& (XINT (addr, 1) == UNSPEC_GOTENT
new file mode 100644
@@ -0,0 +1,11 @@
+/* { dg-do compile } */
+/* { dg-options "-march=z13 -O1" } */
+
+typedef int v4si __attribute__ ((vector_size (16)));
+
+int
+f ()
+{
+ v4si x = {0, 1, 2, 3};
+ return x[4];
+}