This fixes PR82964 which reports ICEs for some CONST_WIDE_INT immediates.
It turns out decimal floating point CONST_DOUBLE get changed into
CONST_WIDE_INT without checking the constraint on the operand, which
results in failures. Avoid this by only allowing SF/DF/TF mode floating
point constants in aarch64_legitimate_constant_p. A similar issue can
occur with 128-bit immediates which may be emitted even when disallowed
in aarch64_legitimate_constant_p, and the constraints in movti_aarch64
don't match. Fix this with a new constraint and allowing valid immediates
in aarch64_legitimate_constant_p.
Rather than allowing all 128-bit immediates and expanding in up to 8
MOV/MOVK instructions, limit them to 4 instructions and use a literal
load for other cases. Improve a few TImode tests to use a literal and
ensure they are skipped with -fpic.
This fixes all reported failures.
gcc/
PR target/82964
* config/aarch64/aarch64.md (movti_aarch64): Use Uti constraint.
* config/aarch64/aarch64.c (aarch64_mov128_immediate): New function.
(aarch64_legitimate_constant_p): Just support CONST_DOUBLE
SF/DF/TF mode to avoid creating illegal CONST_WIDE_INT immediates.
* config/aarch64/aarch64-protos.h (aarch64_mov128_immediate):
Add declaration.
* config/aarch64/constraints.md (aarch64_movti_operand):
Limit immediates.
* config/aarch64/predicates.md (Uti): Add new constraint.
gcc/testsuite/
PR target/79041
PR target/82964
* gcc.target/aarch64/pr79041-2.c: Improve test, disable with fpic.
* gcc.target/aarch64/pr78733.c: Improve test, disable with fpic.
Co-Authored-By: Richard Sandiford <richard.sandiford@linaro.org>
From-SVN: r256800
+2018-01-17 Wilco Dijkstra <wdijkstr@arm.com>
+ Richard Sandiford <richard.sandiford@linaro.org>
+
+ * config/aarch64/aarch64.md (movti_aarch64): Use Uti constraint.
+ * config/aarch64/aarch64.c (aarch64_mov128_immediate): New function.
+ (aarch64_legitimate_constant_p): Just support CONST_DOUBLE
+ SF/DF/TF mode to avoid creating illegal CONST_WIDE_INT immediates.
+ * config/aarch64/aarch64-protos.h (aarch64_mov128_immediate):
+ Add declaration.
+ * config/aarch64/constraints.md (aarch64_movti_operand):
+ Limit immediates.
+ * config/aarch64/predicates.md (Uti): Add new constraint.
+
2018-01-17 Carl Love <cel@us.ibm.com>
* config/rs6000/vsx.md (define_expand xl_len_r,
define_expand stxvl, define_expand *stxvl): Add match_dup argument.
bool aarch64_split_128bit_move_p (rtx, rtx);
+bool aarch64_mov128_immediate (rtx);
+
void aarch64_split_simd_combine (rtx, rtx, rtx);
void aarch64_split_simd_move (rtx, rtx);
return num_insns;
}
+/* Return whether imm is a 128-bit immediate which is simple enough to
+ expand inline. */
+bool
+aarch64_mov128_immediate (rtx imm)
+{
+ if (GET_CODE (imm) == CONST_INT)
+ return true;
+
+ gcc_assert (CONST_WIDE_INT_NUNITS (imm) == 2);
+
+ rtx lo = GEN_INT (CONST_WIDE_INT_ELT (imm, 0));
+ rtx hi = GEN_INT (CONST_WIDE_INT_ELT (imm, 1));
+
+ return aarch64_internal_mov_immediate (NULL_RTX, lo, false, DImode)
+ + aarch64_internal_mov_immediate (NULL_RTX, hi, false, DImode) <= 4;
+}
+
+
/* Return the number of temporary registers that aarch64_add_offset_1
would need to add OFFSET to a register. */
aarch64_legitimate_constant_p (machine_mode mode, rtx x)
{
/* Support CSE and rematerialization of common constants. */
- if (CONST_INT_P (x) || CONST_DOUBLE_P (x) || GET_CODE (x) == CONST_VECTOR)
+ if (CONST_INT_P (x)
+ || (CONST_DOUBLE_P (x)
+ && (mode == SFmode || mode == DFmode || mode == TFmode))
+ || GET_CODE (x) == CONST_VECTOR)
return true;
/* Do not allow vector struct mode constants for Advanced SIMD.
if (vec_flags == (VEC_ADVSIMD | VEC_STRUCT))
return false;
- /* Do not allow wide int constants - this requires support in movti. */
- if (CONST_WIDE_INT_P (x))
- return false;
-
/* Only accept variable-length vector constants if they can be
handled directly.
(define_insn "*movti_aarch64"
[(set (match_operand:TI 0
- "nonimmediate_operand" "=r, w,r,w,r,m,m,w,m")
+ "nonimmediate_operand" "= r,w, r,w,r,m,m,w,m")
(match_operand:TI 1
- "aarch64_movti_operand" " rn,r,w,w,m,r,Z,m,w"))]
+ "aarch64_movti_operand" " rUti,r, w,w,m,r,Z,m,w"))]
"(register_operand (operands[0], TImode)
|| aarch64_reg_or_zero (operands[1], TImode))"
"@
(and (match_code "const_int")
(match_test "aarch64_move_imm (ival, DImode)")))
+(define_constraint "Uti"
+ "A constant that can be used with a 128-bit MOV immediate operation."
+ (and (ior (match_code "const_int")
+ (match_code "const_wide_int"))
+ (match_test "aarch64_mov128_immediate (op)")))
+
(define_constraint "UsO"
"A constant that can be used with a 32-bit and operation."
(and (match_code "const_int")
(match_test "aarch64_mov_operand_p (op, mode)"))))
(define_predicate "aarch64_movti_operand"
- (and (match_code "reg,subreg,mem,const_int")
- (ior (match_operand 0 "register_operand")
- (ior (match_operand 0 "memory_operand")
- (match_operand 0 "const_int_operand")))))
+ (ior (match_operand 0 "register_operand")
+ (match_operand 0 "memory_operand")
+ (and (match_operand 0 "const_scalar_int_operand")
+ (match_test "aarch64_mov128_immediate (op)"))))
(define_predicate "aarch64_reg_or_imm"
- (and (match_code "reg,subreg,const_int")
- (ior (match_operand 0 "register_operand")
- (match_operand 0 "const_int_operand"))))
+ (ior (match_operand 0 "register_operand")
+ (match_operand 0 "const_scalar_int_operand")))
;; True for integer comparisons and for FP comparisons other than LTGT or UNEQ.
(define_special_predicate "aarch64_comparison_operator"
+2018-01-17 Wilco Dijkstra <wdijkstr@arm.com>
+ Richard Sandiford <richard.sandiford@linaro.org>
+
+ PR target/79041
+ PR target/82964
+ * gcc.target/aarch64/pr79041-2.c: Improve test, disable with fpic.
+ * gcc.target/aarch64/pr78733.c: Improve test, disable with fpic.
+
2018-01-17 Kyrylo Tkachov <kyrylo.tkachov@arm.com>
* lib/target-supports.exp: Fix -march arguments in arm arch effective
/* { dg-do compile } */
-/* { dg-options "-O2 -mpc-relative-literal-loads" } */
+/* { dg-options "-O2 -mcmodel=large -mpc-relative-literal-loads" } */
+/* { dg-require-effective-target lp64 } */
+/* { dg-skip-if "-mcmodel=large, no support for -fpic" { aarch64-*-* } { "-fpic" } { "" } } */
__int128
t (void)
{
- return (__int128)1 << 80;
+ return ((__int128)0x123456789abcdef << 64) | 0xfedcba987654321;
}
/* { dg-final { scan-assembler "adr" } } */
+/* { dg-final { scan-assembler-not "adrp" } } */
/* { dg-do compile } */
/* { dg-options "-O2 -mcmodel=large -mpc-relative-literal-loads" } */
/* { dg-require-effective-target lp64 } */
+/* { dg-skip-if "-mcmodel=large, no support for -fpic" { aarch64-*-* } { "-fpic" } { "" } } */
__int128
t (void)
{
- return (__int128)1 << 80;
+ return ((__int128)0x123456789abcdef << 64) | 0xfedcba987654321;
}
/* { dg-final { scan-assembler "adr" } } */