This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
[AArch64] Describe the 'BSL' RTL pattern more accurately.
- From: James Greenhalgh <james dot greenhalgh at arm dot com>
- To: gcc-patches at gcc dot gnu dot org
- Cc: marcus/shawcroft at arm dot com
- Date: Thu, 25 Apr 2013 11:36:36 +0100
- Subject: [AArch64] Describe the 'BSL' RTL pattern more accurately.
Hi,
The aarch64_simd_bsl<mode> pattern performs an operation which can
be described in C as:
(a & b) | (~a & c)
Rewriting this in RTL rather than using an UNSPEC allows for
better constant folding.
Regression tested for aarch64-none-elf with no regressions.
OK?
Thanks,
James
---
gcc/
2013-04-25 James Greenhalgh <james.greenhalgh@arm.com>
* config/aarch64/aarch64-simd.md
(aarch64_simd_bsl<mode>_internal): Rewrite RTL to not use UNSPEC_BSL.
(aarch64_simd_bsl<mode>): Likewise.
* config/aarch64/iterators.md (unspec): Remove UNSPEC_BSL.
diff --git a/gcc/config/aarch64/aarch64-simd.md b/gcc/config/aarch64/aarch64-simd.md
index 42c8d68..5862d26 100644
--- a/gcc/config/aarch64/aarch64-simd.md
+++ b/gcc/config/aarch64/aarch64-simd.md
@@ -1509,21 +1509,33 @@
(set_attr "simd_mode" "V2SI")]
)
-;; vbsl_* intrinsics may compile to any of bsl/bif/bit depending on register
-;; allocation. For an intrinsic of form:
-;; vD = bsl_* (vS, vN, vM)
+;; aarch64_simd_bsl may compile to any of bsl/bif/bit depending on register
+;; allocation.
+;; Operand 1 is the mask, operands 2 and 3 are the bitfields from which
+;; to select.
+;;
+;; Thus our BSL is of the form:
+;; op0 = bsl (mask, op2, op3)
;; We can use any of:
-;; bsl vS, vN, vM (if D = S)
-;; bit vD, vN, vS (if D = M, so 1-bits in vS choose bits from vN, else vM)
-;; bif vD, vM, vS (if D = N, so 0-bits in vS choose bits from vM, else vN)
+;;
+;; if (op0 = mask)
+;; bsl mask, op1, op2
+;; if (op0 = op1) (so 1-bits in mask choose bits from op2, else op0)
+;; bit op0, op2, mask
+;; if (op0 = op2) (so 0-bits in mask choose bits from op1, else op0)
+;; bif op0, op1, mask
(define_insn "aarch64_simd_bsl<mode>_internal"
[(set (match_operand:VALL 0 "register_operand" "=w,w,w")
- (unspec:VALL
- [(match_operand:<V_cmp_result> 1 "register_operand" " 0,w,w")
- (match_operand:VALL 2 "register_operand" " w,w,0")
- (match_operand:VALL 3 "register_operand" " w,0,w")]
- UNSPEC_BSL))]
+ (ior:VALL
+ (and:VALL
+ (match_operand:<V_cmp_result> 1 "register_operand" " 0,w,w")
+ (match_operand:VALL 2 "register_operand" " w,w,0"))
+ (and:VALL
+ (not:<V_cmp_result>
+ (match_dup:<V_cmp_result> 1))
+ (match_operand:VALL 3 "register_operand" " w,0,w"))
+ ))]
"TARGET_SIMD"
"@
bsl\\t%0.<Vbtype>, %2.<Vbtype>, %3.<Vbtype>
@@ -1532,15 +1544,17 @@
)
(define_expand "aarch64_simd_bsl<mode>"
- [(set (match_operand:VALL 0 "register_operand")
- (unspec:VALL [(match_operand:<V_cmp_result> 1 "register_operand")
- (match_operand:VALL 2 "register_operand")
- (match_operand:VALL 3 "register_operand")]
- UNSPEC_BSL))]
- "TARGET_SIMD"
+ [(match_operand:VALL 0 "register_operand")
+ (match_operand:<V_cmp_result> 1 "register_operand")
+ (match_operand:VALL 2 "register_operand")
+ (match_operand:VALL 3 "register_operand")]
+ "TARGET_SIMD"
{
/* We can't alias operands together if they have different modes. */
operands[1] = gen_lowpart (<V_cmp_result>mode, operands[1]);
+ emit_insn (gen_aarch64_simd_bsl<mode>_internal (operands[0], operands[1],
+ operands[2], operands[3]));
+ DONE;
})
(define_expand "aarch64_vcond_internal<mode>"
diff --git a/gcc/config/aarch64/iterators.md b/gcc/config/aarch64/iterators.md
index 017e128..58a2a9e 100644
--- a/gcc/config/aarch64/iterators.md
+++ b/gcc/config/aarch64/iterators.md
@@ -230,7 +230,6 @@
UNSPEC_CMTST ; Used in aarch64-simd.md.
UNSPEC_FMAX ; Used in aarch64-simd.md.
UNSPEC_FMIN ; Used in aarch64-simd.md.
- UNSPEC_BSL ; Used in aarch64-simd.md.
UNSPEC_TBL ; Used in vector permute patterns.
UNSPEC_CONCAT ; Used in vector permute patterns.
UNSPEC_ZIP1 ; Used in vector permute patterns.