Commit 64c744b9 by Dominik Vogt Committed by Andreas Krebbel

S/390: Improved risbg usage.

gcc/ChangeLog:

2016-09-23  Dominik Vogt  <vogt@linux.vnet.ibm.com>

	* config/s390/s390.md ("*extzv<mode>_zEC12", "*extzv<mode>_z10")
	("*extzv<mode><clobbercc_or_nocc>"):
	Correct a typo in a comment.
	Merged patterns.
	("*insv<mode>_zEC12", "*insv<mode>_z10")
	("*insv<mode><clobbercc_or_nocc>"): Ditto.
	("*insv<mode>_zEC12_appendbitsleft")
	("*insv<mode><clobbercc_or_nocc>_appendbitsleft")
	("*insv<mode>_z10_appendbitsleft"): Ditto.
	("*insv<mode>_zEC12_noshift", "*insv<mode>_z10_noshift")
	("*insv<mode><clobbercc_or_nocc>_noshift"): Ditto.
	Provide pattern with operands switched.
	("*pre_z10_extv<mode>"):
	Use new subst patterns.
	("*extzvdi<clobbercc_or_nocc>_lshiftrt", "*<risbg_n>_ior_and_sr_ze")
	("*extvsidi<clobbercc_or_nocc>", "*<risbg_n>_and_subregdi_rotr")
	("*<risbg_n>_and_subregdi_rotl", "*<risbg_n>_di_and_rot")
	("*insv_z10_noshift_cc", "*insv_z10_noshift_cconly")
	("*<risbg_n>_<mode>_ior_and_lshiftrt")
	("*<risbg_n>_sidi_ior_and_lshiftrt")
	("*trunc_sidi_and_subreg_lshrt<clobbercc_or_nocc>"):
	New patterns.
	("*extzv_<mode>_sll", "*extzv_<mode>_srl")
	("*extzv_<mode>_srl<clobbercc_or_nocc>")
	("*extzv_<mode>_sll<clobbercc_or_nocc>"): Renamed patterns, use risbgn
	on zEC12.
	("SINT"): New mode_iterator with SI, HI, QI.
	* config/s390/subst.md ("clobbercc_or_nocc_subst", "z10_or_zEC12_cond")
	("clobbercc_or_nocc", "risbg_n"): New constructs for risbg pattern
	duplication.
	
gcc/testsuite/ChangeLog:

2016-09-23  Dominik Vogt  <vogt@linux.vnet.ibm.com>

	* gcc.target/s390/risbg-ll-1.c: Ported risbg tests from llvm.
	* gcc.target/s390/risbg-ll-2.c: Ditto.
	* gcc.target/s390/risbg-ll-3.c: Ditto.

From-SVN: r240414
parent c2586c82
2016-09-23 Dominik Vogt <vogt@linux.vnet.ibm.com>
* config/s390/s390.md ("*extzv<mode>_zEC12", "*extzv<mode>_z10")
("*extzv<mode><clobbercc_or_nocc>"):
Correct a typo in a comment.
Merged patterns.
("*insv<mode>_zEC12", "*insv<mode>_z10")
("*insv<mode><clobbercc_or_nocc>"): Ditto.
("*insv<mode>_zEC12_appendbitsleft")
("*insv<mode><clobbercc_or_nocc>_appendbitsleft")
("*insv<mode>_z10_appendbitsleft"): Ditto.
("*insv<mode>_zEC12_noshift", "*insv<mode>_z10_noshift")
("*insv<mode><clobbercc_or_nocc>_noshift"): Ditto.
Provide pattern with operands switched.
("*pre_z10_extv<mode>"):
Use new subst patterns.
("*extzvdi<clobbercc_or_nocc>_lshiftrt", "*<risbg_n>_ior_and_sr_ze")
("*extvsidi<clobbercc_or_nocc>", "*<risbg_n>_and_subregdi_rotr")
("*<risbg_n>_and_subregdi_rotl", "*<risbg_n>_di_and_rot")
("*insv_z10_noshift_cc", "*insv_z10_noshift_cconly")
("*<risbg_n>_<mode>_ior_and_lshiftrt")
("*<risbg_n>_sidi_ior_and_lshiftrt")
("*trunc_sidi_and_subreg_lshrt<clobbercc_or_nocc>"):
New patterns.
("*extzv_<mode>_sll", "*extzv_<mode>_srl")
("*extzv_<mode>_srl<clobbercc_or_nocc>")
("*extzv_<mode>_sll<clobbercc_or_nocc>"): Renamed patterns, use risbgn
on zEC12.
("SINT"): New mode_iterator with SI, HI, QI.
* config/s390/subst.md ("clobbercc_or_nocc_subst", "z10_or_zEC12_cond")
("clobbercc_or_nocc", "risbg_n"): New constructs for risbg pattern
duplication.
2016-09-23 Dominik Vogt <vogt@linux.vnet.ibm.com>
* config/s390/predicates.md ("contiguous_bitmask_operand"): Adapt to new
interface of s390_contiguous_bitmask_p.
("contiguous_bitmask_nowrap_operand"): New predicate.
......
......@@ -120,3 +120,24 @@
(clobber (match_scratch:DSI 0 "=d,d"))])
(define_subst_attr "cconly" "cconly_subst" "" "_cconly")
; Does transformations to switch between patterns unsing risbg +
; clobber CC (z10) and risbgn without clobber (zEC12).
(define_subst "clobbercc_or_nocc_subst"
[(set (match_operand 0 "" "") (match_operand 1 "" ""))]
""
[(set (match_dup 0) (match_dup 1))
(clobber (reg:CC CC_REGNUM))])
; Use this in the insn name to add the target suffix.
(define_subst_attr "clobbercc_or_nocc" "clobbercc_or_nocc_subst"
"_nocc" "_clobbercc")
; Use this in the condition.
(define_subst_attr "z10_or_zEC12_cond" "clobbercc_or_nocc_subst"
"TARGET_ZEC12" "TARGET_Z10 && ! TARGET_ZEC12")
; Use this instead of the risbg instruction.
(define_subst_attr "risbg_n" "clobbercc_or_nocc_subst"
"risbgn" "risbg")
2016-09-23 Dominik Vogt <vogt@linux.vnet.ibm.com>
* gcc.target/s390/risbg-ll-1.c: Ported risbg tests from llvm.
* gcc.target/s390/risbg-ll-2.c: Ditto.
* gcc.target/s390/risbg-ll-3.c: Ditto.
2016-09-23 Matthew Wahab <matthew.wahab@arm.com>
* gcc.target/arm/armv8_2-fp16-arith-1.c: New.
......
// Test sequences that can use RISBG with a normal first operand.
/* Tests ported from the Llvm testsuite. */
/* { dg-do compile { target s390x-*-* } } */
/* { dg-options "-O3 -march=z10 -mzarch -fno-asynchronous-unwind-tables" } */
#define i64 signed long long
#define ui64 unsigned long long
#define i32 signed int
#define ui32 unsigned int
// Test a case with two ANDs.
i32 f1 (i32 v_a, i32 v_b)
{
/* { dg-final { scan-assembler "f1:\n\trisbg\t%r2,%r3,60,62,0" } } */
i32 v_anda = v_a & -15;
i32 v_andb = v_b & 14;
i32 v_or = v_anda | v_andb;
return v_or;
}
// ...and again with i64.
i64 f2 (i64 v_a, i64 v_b)
{
/* { dg-final { scan-assembler "f2:\n\trisbg\t%r2,%r3,60,62,0" { target { lp64 } } } } */
/* { dg-final { scan-assembler "f2:\n\trisbg\t%r3,%r2,0,0\\\+32-1,64-0-32\n\(\t.*\n\)*\trisbg\t%r\[23\],%r5,60,62,0" { target { ! lp64 } } } } */
i64 v_anda = v_a & -15;
i64 v_andb = v_b & 14;
i64 v_or = v_anda | v_andb;
return v_or;
}
// Test a case with two ANDs and a shift.
i32 f3 (i32 v_a, i32 v_b)
{
/* { dg-final { scan-assembler "f3:\n\trisbg\t%r2,%r3,64-4,63,4\\\+52" } } */
i32 v_anda = v_a & -16;
i32 v_shr = ((ui32)v_b) >> 8;
i32 v_andb = v_shr & 15;
i32 v_or = v_anda | v_andb;
return v_or;
}
// ...and again with i64.
i64 f4 (i64 v_a, i64 v_b)
{
/* { dg-final { scan-assembler "f4:\n\trisbg\t%r2,%r3,60,60\\\+4-1,128-60-4-8" { target { lp64 } } } } */
/* { dg-final { scan-assembler "f4:\n\(\t.*\n\)*\trisbg\t%r5,%r5,64-4,128\\\+63,52\\\+4" { target { ! lp64 } } } } */
i64 v_anda = v_a & -16;
i64 v_shr = ((ui64)v_b) >> 8;
i64 v_andb = v_shr & 15;
i64 v_or = v_anda | v_andb;
return v_or;
}
// Test a case with a single AND and a left shift.
i32 f5 (i32 v_a, i32 v_b)
{
/* { dg-final { scan-assembler "f5:\n\trisbg\t%r2,%r3,32,64-10-1,10" } } */
i32 v_anda = v_a & 1023;
i32 v_shlb = v_b << 10;
i32 v_or = v_anda | v_shlb;
return v_or;
}
// ...and again with i64.
i64 f6 (i64 v_a, i64 v_b)
{
/* { dg-final { scan-assembler "f6:\n\trisbg\t%r2,%r3,0,64-10-1,10" { target { lp64 } } } } */
/* { dg-final { scan-assembler "f6:\n\trisbg\t%r5,%r4,0,0\\\+32-1,64-0-32\n\(\t.*\n\)*\trisbg\t%r\[23\],%r5,0,64-10-1,10" { target { ! lp64 } } } } */
i64 v_anda = v_a & 1023;
i64 v_shlb = v_b << 10;
i64 v_or = v_anda | v_shlb;
return v_or;
}
// Test a case with a single AND and a right shift.
i32 f7 (i32 v_a, i32 v_b)
{
/* { dg-final { scan-assembler "f7:\n\trisbg\t%r2,%r3,32\\\+8,63,64-8" } } */
i32 v_anda = v_a & -16777216;
i32 v_shrb = ((ui32)v_b) >> 8;
i32 v_or = v_anda | v_shrb;
return v_or;
}
// ...and again with i64.
i64 f8 (i64 v_a, i64 v_b)
{
/* { dg-final { scan-assembler "f8:\n\trisbg\t%r2,%r3,8,63,64-8" { target { lp64 } } } } */
/* With -m31 risbg is not really useful here, so do not test for it. */
i64 v_anda = v_a & -72057594037927936;
i64 v_shrb = ((ui64)v_b) >> 8;
i64 v_or = v_anda | v_shrb;
return v_or;
}
// Check that we can get the case where a 64-bit shift feeds a 32-bit or of
// ands with complement masks.
i32 f9 (i64 v_x, i32 v_y)
{
/* { dg-final { scan-assembler "f9:\n\trisbg\t%r3,%r2,48,63,64-48" { target { lp64 } }} } */
/* { dg-final { scan-assembler "f9:\n\trisbg\t%r4,%r2,32\\+16,63,64-16" { target { ! lp64 } }} } */
i64 v_shr6 = ((ui64)v_x) >> 48;
i32 v_conv = (ui32)v_shr6;
i32 v_and1 = v_y & -65536;
i32 v_or = v_conv | v_and1;
return v_or;
}
// Check that we don't get the case where a 64-bit shift feeds a 32-bit or of
// ands with incompatible masks.
i32 f10 (i64 v_x, i32 v_y)
{
/* { dg-final { scan-assembler "f10:\n\tsrlg\t%r2,%r2,48\n\trosbg\t%r2,%r3,32,39,0" { target { lp64 } } } } */
/* { dg-final { scan-assembler "f10:\n\tnilf\t%r4,4278190080\n\trosbg\t%r4,%r2,32\\\+16,63,64-16" { target { ! lp64 } } } } */
i64 v_shr6 = ((ui64)v_x) >> 48;
i32 v_conv = (ui32)v_shr6;
i32 v_and1 = v_y & -16777216;
i32 v_or = v_conv | v_and1;
return v_or;
}
// Test use of RISBG vs RISBGN on zEC12.
/* Tests ported from the Llvm testsuite. */
/* { dg-do compile { target s390x-*-* } } */
/* { dg-options "-O3 -march=zEC12 -mzarch -fno-asynchronous-unwind-tables" } */
#define i64 signed long long
#define ui64 unsigned long long
// On zEC12, we generally prefer RISBGN.
i64 f1 (i64 v_a, i64 v_b)
{
/* { dg-final { scan-assembler "f1:\n\trisbgn\t%r2,%r3,60,60\\\+3-1,128-60-3-1" { target { lp64 } } } } */
/* { dg-final { scan-assembler "f1:\n\trisbgn\t%r3,%r2,0,0\\\+32-1,64-0-32\n\trisbgn\t%r3,%r5,60,62,0\n" { target { ! lp64 } } } } */
i64 v_anda = v_a & -15;
i64 v_andb = v_b & 14;
i64 v_or = v_anda | v_andb;
return v_or;
}
// But we may fall back to RISBG if we can use the condition code.
extern i64 f2_foo();
i64 f2 (i64 v_a, i64 v_b)
{
/* { dg-final { scan-assembler "f2:\n\trisbg\t%r2,%r3,60,62,0\n\tje\t" { target { lp64 } } } } */
/* { dg-final { scan-assembler "f2:\n\trisbgn\t%r3,%r2,0,0\\\+32-1,64-0-32\n\trisbg\t%r3,%r5,60,62,0" { target { ! lp64 } } } } */
i64 v_anda = v_a & -15;
i64 v_andb = v_b & 14;
i64 v_or = v_anda | v_andb;
if (! v_or)
return f2_foo();
else
return v_or;
}
void f2_bar ();
void f2_cconly (i64 v_a, i64 v_b)
{
/* { dg-final { scan-assembler "f2_cconly:\n\trisbg\t%r3,%r2,63,59,0\n\tjne\t" { target { lp64 } } } } */
/* { dg-final { scan-assembler "f2_cconly:\n\trisbgn\t%r3,%r2,0,0\\\+32-1,64-0-32\n\trisbg\t%r3,%r5,60,62,0\n\tjne\t" { target { ! lp64 } } } } */
if ((v_a & -15) | (v_b & 14))
f2_bar();
}
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