Patchwork [AArch64] Describe the 'BSL' RTL pattern more accurately.

login
register
mail settings
Submitter James Greenhalgh
Date April 25, 2013, 10:36 a.m.
Message ID <1366886196-6752-1-git-send-email-james.greenhalgh@arm.com>
Download mbox | patch
Permalink /patch/239481/
State New
Headers show

Comments

James Greenhalgh - April 25, 2013, 10:36 a.m.
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.
Marcus Shawcroft - April 25, 2013, 4:04 p.m.
On 25/04/13 11:36, James Greenhalgh wrote:
>
> 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.
>

Looks OK to me.
/Marcus

Patch

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.