Commit f22d7973 by Richard Sandiford Committed by Richard Sandiford

[AArch64] Use UNSPEC_MERGE_PTRUE for comparisons

This patch rewrites the SVE comparison handling so that it uses
UNSPEC_MERGE_PTRUE for comparisons that are known to be predicated
on a PTRUE, for consistency with other patterns.  Specific unspecs
are then only needed for truly predicated floating-point comparisons,
such as those used in the expansion of UNEQ for flag_trapping_math.

The patch also makes sure that the comparison expanders attach
a REG_EQUAL note to instructions that use UNSPEC_MERGE_PTRUE,
so passes can use that as an alternative to the unspec pattern.
(This happens automatically for optabs.  The problem was that
this code emits instruction patterns directly.)

No specific benefit on its own, but it lays the groundwork for
the next patch.

2018-05-08  Richard Sandiford  <richard.sandiford@linaro.org>

gcc/
	* config/aarch64/iterators.md (UNSPEC_COND_LO, UNSPEC_COND_LS)
	(UNSPEC_COND_HI, UNSPEC_COND_HS, UNSPEC_COND_UO): Delete.
	(SVE_INT_CMP, SVE_FP_CMP): New code iterators.
	(cmp_op, sve_imm_con): New code attributes.
	(SVE_COND_INT_CMP, imm_con): Delete.
	(cmp_op): Remove above unspecs from int attribute.
	* config/aarch64/aarch64-sve.md (*vec_cmp<cmp_op>_<mode>): Rename
	to...
	(*cmp<cmp_op><mode>): ...this.  Use UNSPEC_MERGE_PTRUE instead of
	comparison-specific unspecs.
	(*vec_cmp<cmp_op>_<mode>_ptest): Rename to...
	(*cmp<cmp_op><mode>_ptest): ...this and adjust likewise.
	(*vec_cmp<cmp_op>_<mode>_cc): Rename to...
	(*cmp<cmp_op><mode>_cc): ...this and adjust likewise.
	(*vec_fcm<cmp_op><mode>): Rename to...
	(*fcm<cmp_op><mode>): ...this and adjust likewise.
	(*vec_fcmuo<mode>): Rename to...
	(*fcmuo<mode>): ...this and adjust likewise.
	(*pred_fcm<cmp_op><mode>): New pattern.
	* config/aarch64/aarch64.c (aarch64_emit_unop, aarch64_emit_binop)
	(aarch64_emit_sve_ptrue_op, aarch64_emit_sve_ptrue_op_cc): New
	functions.
	(aarch64_unspec_cond_code): Remove handling of LTU, GTU, LEU, GEU
	and UNORDERED.
	(aarch64_gen_unspec_cond, aarch64_emit_unspec_cond): Delete.
	(aarch64_emit_sve_predicated_cond): New function.
	(aarch64_expand_sve_vec_cmp_int): Use aarch64_emit_sve_ptrue_op_cc.
	(aarch64_emit_unspec_cond_or): Replace with...
	(aarch64_emit_sve_or_conds): ...this new function.  Use
	aarch64_emit_sve_ptrue_op for the individual comparisons and
	aarch64_emit_binop to OR them together.
	(aarch64_emit_inverted_unspec_cond): Replace with...
	(aarch64_emit_sve_inverted_cond): ...this new function.  Use
	aarch64_emit_sve_ptrue_op for the comparison and
	aarch64_emit_unop to invert the result.
	(aarch64_expand_sve_vec_cmp_float): Update after the above
	changes.  Use aarch64_emit_sve_ptrue_op for native comparisons.

From-SVN: r260029
parent 4fdd8b18
2018-05-08 Richard Sandiford <richard.sandiford@linaro.org>
* config/aarch64/iterators.md (UNSPEC_COND_LO, UNSPEC_COND_LS)
(UNSPEC_COND_HI, UNSPEC_COND_HS, UNSPEC_COND_UO): Delete.
(SVE_INT_CMP, SVE_FP_CMP): New code iterators.
(cmp_op, sve_imm_con): New code attributes.
(SVE_COND_INT_CMP, imm_con): Delete.
(cmp_op): Remove above unspecs from int attribute.
* config/aarch64/aarch64-sve.md (*vec_cmp<cmp_op>_<mode>): Rename
to...
(*cmp<cmp_op><mode>): ...this. Use UNSPEC_MERGE_PTRUE instead of
comparison-specific unspecs.
(*vec_cmp<cmp_op>_<mode>_ptest): Rename to...
(*cmp<cmp_op><mode>_ptest): ...this and adjust likewise.
(*vec_cmp<cmp_op>_<mode>_cc): Rename to...
(*cmp<cmp_op><mode>_cc): ...this and adjust likewise.
(*vec_fcm<cmp_op><mode>): Rename to...
(*fcm<cmp_op><mode>): ...this and adjust likewise.
(*vec_fcmuo<mode>): Rename to...
(*fcmuo<mode>): ...this and adjust likewise.
(*pred_fcm<cmp_op><mode>): New pattern.
* config/aarch64/aarch64.c (aarch64_emit_unop, aarch64_emit_binop)
(aarch64_emit_sve_ptrue_op, aarch64_emit_sve_ptrue_op_cc): New
functions.
(aarch64_unspec_cond_code): Remove handling of LTU, GTU, LEU, GEU
and UNORDERED.
(aarch64_gen_unspec_cond, aarch64_emit_unspec_cond): Delete.
(aarch64_emit_sve_predicated_cond): New function.
(aarch64_expand_sve_vec_cmp_int): Use aarch64_emit_sve_ptrue_op_cc.
(aarch64_emit_unspec_cond_or): Replace with...
(aarch64_emit_sve_or_conds): ...this new function. Use
aarch64_emit_sve_ptrue_op for the individual comparisons and
aarch64_emit_binop to OR them together.
(aarch64_emit_inverted_unspec_cond): Replace with...
(aarch64_emit_sve_inverted_cond): ...this new function. Use
aarch64_emit_sve_ptrue_op for the comparison and
aarch64_emit_unop to invert the result.
(aarch64_expand_sve_vec_cmp_float): Update after the above
changes. Use aarch64_emit_sve_ptrue_op for native comparisons.
2018-05-07 Nathan Sidwell <nathan@acm.org>
* doc/invoke.texi (C++ Dialect Options): Remove -ffor-scope.
......
......@@ -1292,14 +1292,15 @@
}
)
;; Predicated integer comparison.
(define_insn "*vec_cmp<cmp_op>_<mode>"
;; Integer comparisons predicated with a PTRUE.
(define_insn "*cmp<cmp_op><mode>"
[(set (match_operand:<VPRED> 0 "register_operand" "=Upa, Upa")
(unspec:<VPRED>
[(match_operand:<VPRED> 1 "register_operand" "Upl, Upl")
(match_operand:SVE_I 2 "register_operand" "w, w")
(match_operand:SVE_I 3 "aarch64_sve_cmp_<imm_con>_operand" "<imm_con>, w")]
SVE_COND_INT_CMP))
(SVE_INT_CMP:<VPRED>
(match_operand:SVE_I 2 "register_operand" "w, w")
(match_operand:SVE_I 3 "aarch64_sve_cmp_<sve_imm_con>_operand" "<sve_imm_con>, w"))]
UNSPEC_MERGE_PTRUE))
(clobber (reg:CC CC_REGNUM))]
"TARGET_SVE"
"@
......@@ -1307,17 +1308,19 @@
cmp<cmp_op>\t%0.<Vetype>, %1/z, %2.<Vetype>, %3.<Vetype>"
)
;; Predicated integer comparison in which only the flags result is interesting.
(define_insn "*vec_cmp<cmp_op>_<mode>_ptest"
;; Integer comparisons predicated with a PTRUE in which only the flags result
;; is interesting.
(define_insn "*cmp<cmp_op><mode>_ptest"
[(set (reg:CC CC_REGNUM)
(compare:CC
(unspec:SI
[(match_operand:<VPRED> 1 "register_operand" "Upl, Upl")
(unspec:<VPRED>
[(match_dup 1)
(match_operand:SVE_I 2 "register_operand" "w, w")
(match_operand:SVE_I 3 "aarch64_sve_cmp_<imm_con>_operand" "<imm_con>, w")]
SVE_COND_INT_CMP)]
(SVE_INT_CMP:<VPRED>
(match_operand:SVE_I 2 "register_operand" "w, w")
(match_operand:SVE_I 3 "aarch64_sve_cmp_<sve_imm_con>_operand" "<sve_imm_con>, w"))]
UNSPEC_MERGE_PTRUE)]
UNSPEC_PTEST_PTRUE)
(const_int 0)))
(clobber (match_scratch:<VPRED> 0 "=Upa, Upa"))]
......@@ -1327,59 +1330,76 @@
cmp<cmp_op>\t%0.<Vetype>, %1/z, %2.<Vetype>, %3.<Vetype>"
)
;; Predicated comparison in which both the flag and predicate results
;; are interesting.
(define_insn "*vec_cmp<cmp_op>_<mode>_cc"
;; Integer comparisons predicated with a PTRUE in which both the flag and
;; predicate results are interesting.
(define_insn "*cmp<cmp_op><mode>_cc"
[(set (reg:CC CC_REGNUM)
(compare:CC
(unspec:SI
[(match_operand:<VPRED> 1 "register_operand" "Upl, Upl")
(unspec:<VPRED>
[(match_dup 1)
(match_operand:SVE_I 2 "register_operand" "w, w")
(match_operand:SVE_I 3 "aarch64_sve_cmp_<imm_con>_operand" "<imm_con>, w")]
SVE_COND_INT_CMP)]
(SVE_INT_CMP:<VPRED>
(match_operand:SVE_I 2 "register_operand" "w, w")
(match_operand:SVE_I 3 "aarch64_sve_cmp_<sve_imm_con>_operand" "<sve_imm_con>, w"))]
UNSPEC_MERGE_PTRUE)]
UNSPEC_PTEST_PTRUE)
(const_int 0)))
(set (match_operand:<VPRED> 0 "register_operand" "=Upa, Upa")
(unspec:<VPRED>
[(match_dup 1)
(match_dup 2)
(match_dup 3)]
SVE_COND_INT_CMP))]
(SVE_INT_CMP:<VPRED>
(match_dup 2)
(match_dup 3))]
UNSPEC_MERGE_PTRUE))]
"TARGET_SVE"
"@
cmp<cmp_op>\t%0.<Vetype>, %1/z, %2.<Vetype>, #%3
cmp<cmp_op>\t%0.<Vetype>, %1/z, %2.<Vetype>, %3.<Vetype>"
)
;; Predicated floating-point comparison (excluding FCMUO, which doesn't
;; allow #0.0 as an operand).
(define_insn "*vec_fcm<cmp_op><mode>"
;; Floating-point comparisons predicated with a PTRUE.
(define_insn "*fcm<cmp_op><mode>"
[(set (match_operand:<VPRED> 0 "register_operand" "=Upa, Upa")
(unspec:<VPRED>
[(match_operand:<VPRED> 1 "register_operand" "Upl, Upl")
(match_operand:SVE_F 2 "register_operand" "w, w")
(match_operand:SVE_F 3 "aarch64_simd_reg_or_zero" "Dz, w")]
SVE_COND_FP_CMP))]
(SVE_FP_CMP:<VPRED>
(match_operand:SVE_F 2 "register_operand" "w, w")
(match_operand:SVE_F 3 "aarch64_simd_reg_or_zero" "Dz, w"))]
UNSPEC_MERGE_PTRUE))]
"TARGET_SVE"
"@
fcm<cmp_op>\t%0.<Vetype>, %1/z, %2.<Vetype>, #0.0
fcm<cmp_op>\t%0.<Vetype>, %1/z, %2.<Vetype>, %3.<Vetype>"
)
;; Predicated FCMUO.
(define_insn "*vec_fcmuo<mode>"
(define_insn "*fcmuo<mode>"
[(set (match_operand:<VPRED> 0 "register_operand" "=Upa")
(unspec:<VPRED>
[(match_operand:<VPRED> 1 "register_operand" "Upl")
(match_operand:SVE_F 2 "register_operand" "w")
(match_operand:SVE_F 3 "register_operand" "w")]
UNSPEC_COND_UO))]
(unordered:<VPRED>
(match_operand:SVE_F 2 "register_operand" "w")
(match_operand:SVE_F 3 "register_operand" "w"))]
UNSPEC_MERGE_PTRUE))]
"TARGET_SVE"
"fcmuo\t%0.<Vetype>, %1/z, %2.<Vetype>, %3.<Vetype>"
)
;; Predicated floating-point comparisons. We don't need a version
;; of this for unordered comparisons.
(define_insn "*pred_fcm<cmp_op><mode>"
[(set (match_operand:<VPRED> 0 "register_operand" "=Upa, Upa")
(unspec:<VPRED>
[(match_operand:<VPRED> 1 "register_operand" "Upl, Upl")
(match_operand:SVE_F 2 "register_operand" "w, w")
(match_operand:SVE_F 3 "aarch64_simd_reg_or_zero" "Dz, w")]
SVE_COND_FP_CMP))]
"TARGET_SVE"
"@
fcm<cmp_op>\t%0.<Vetype>, %1/z, %2.<Vetype>, #0.0
fcm<cmp_op>\t%0.<Vetype>, %1/z, %2.<Vetype>, %3.<Vetype>"
)
;; vcond_mask operand order: true, false, mask
;; UNSPEC_SEL operand order: mask, true, false (as for VEC_COND_EXPR)
;; SEL operand order: mask, true, false
......
......@@ -455,11 +455,6 @@
UNSPEC_COND_NE ; Used in aarch64-sve.md.
UNSPEC_COND_GE ; Used in aarch64-sve.md.
UNSPEC_COND_GT ; Used in aarch64-sve.md.
UNSPEC_COND_LO ; Used in aarch64-sve.md.
UNSPEC_COND_LS ; Used in aarch64-sve.md.
UNSPEC_COND_HS ; Used in aarch64-sve.md.
UNSPEC_COND_HI ; Used in aarch64-sve.md.
UNSPEC_COND_UO ; Used in aarch64-sve.md.
UNSPEC_LASTB ; Used in aarch64-sve.md.
])
......@@ -1189,6 +1184,12 @@
;; SVE floating-point unary operations.
(define_code_iterator SVE_FP_UNARY [neg abs sqrt])
;; SVE integer comparisons.
(define_code_iterator SVE_INT_CMP [lt le eq ne ge gt ltu leu geu gtu])
;; SVE floating-point comparisons.
(define_code_iterator SVE_FP_CMP [lt le eq ne ge gt])
;; -------------------------------------------------------------------
;; Code Attributes
;; -------------------------------------------------------------------
......@@ -1252,6 +1253,18 @@
(ltu "LTU") (leu "LEU") (ne "NE") (geu "GEU")
(gtu "GTU")])
;; The AArch64 condition associated with an rtl comparison code.
(define_code_attr cmp_op [(lt "lt")
(le "le")
(eq "eq")
(ne "ne")
(ge "ge")
(gt "gt")
(ltu "lo")
(leu "ls")
(geu "hs")
(gtu "hi")])
(define_code_attr fix_trunc_optab [(fix "fix_trunc")
(unsigned_fix "fixuns_trunc")])
......@@ -1358,6 +1371,18 @@
(abs "fabs")
(sqrt "fsqrt")])
;; The SVE immediate constraint to use for an rtl code.
(define_code_attr sve_imm_con [(eq "vsc")
(ne "vsc")
(lt "vsc")
(ge "vsc")
(le "vsc")
(gt "vsc")
(ltu "vsd")
(leu "vsd")
(geu "vsd")
(gtu "vsd")])
;; -------------------------------------------------------------------
;; Int Iterators.
;; -------------------------------------------------------------------
......@@ -1483,12 +1508,6 @@
(define_int_iterator SVE_COND_FP_OP [UNSPEC_COND_ADD UNSPEC_COND_SUB])
(define_int_iterator SVE_COND_INT_CMP [UNSPEC_COND_LT UNSPEC_COND_LE
UNSPEC_COND_EQ UNSPEC_COND_NE
UNSPEC_COND_GE UNSPEC_COND_GT
UNSPEC_COND_LO UNSPEC_COND_LS
UNSPEC_COND_HS UNSPEC_COND_HI])
(define_int_iterator SVE_COND_FP_CMP [UNSPEC_COND_LT UNSPEC_COND_LE
UNSPEC_COND_EQ UNSPEC_COND_NE
UNSPEC_COND_GE UNSPEC_COND_GT])
......@@ -1730,23 +1749,7 @@
(UNSPEC_COND_EQ "eq")
(UNSPEC_COND_NE "ne")
(UNSPEC_COND_GE "ge")
(UNSPEC_COND_GT "gt")
(UNSPEC_COND_LO "lo")
(UNSPEC_COND_LS "ls")
(UNSPEC_COND_HS "hs")
(UNSPEC_COND_HI "hi")])
;; The constraint to use for an UNSPEC_COND_<xx>.
(define_int_attr imm_con [(UNSPEC_COND_EQ "vsc")
(UNSPEC_COND_NE "vsc")
(UNSPEC_COND_LT "vsc")
(UNSPEC_COND_GE "vsc")
(UNSPEC_COND_LE "vsc")
(UNSPEC_COND_GT "vsc")
(UNSPEC_COND_LO "vsd")
(UNSPEC_COND_LS "vsd")
(UNSPEC_COND_HS "vsd")
(UNSPEC_COND_HI "vsd")])
(UNSPEC_COND_GT "gt")])
(define_int_attr sve_int_op [(UNSPEC_COND_ADD "add")
(UNSPEC_COND_SUB "sub")
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment