S/390: arch13: Support new bit operations

Make use of the new bit operation instructions when generating code
for the arch13 level.

gcc/ChangeLog:

2019-04-02  Andreas Krebbel  <krebbel@linux.ibm.com>

	* config/s390/s390.c (s390_canonicalize_comparison): Convert
	certain compares for arch13 in order to make use of the condition
	code result produced by the new instructions.
	(s390_rtx_costs): Adjust the costs for nnrk, nngrk, nork, nogrk,
	nxrk, and nxgrk instruction patterns.
	* config/s390/s390.md (ANDOR, bitops_name, inv_bitops_name)
	(inv_no): Add new code iterator together with some attributes.
	("*andc_split_<mode>"): Disable splitter for arch13.
	("*<ANDOR:bitops_name>c<GPR:mode>_cc")
	("*<ANDOR:bitops_name>c<GPR:mode>_cconly")
	("*<ANDOR:bitops_name>c<GPR:mode>")
	("*n<ANDOR:inv_bitops_name><GPR:mode>_cc")
	("*n<ANDOR:inv_bitops_name><mode>_cconly")
	("*n<ANDOR:inv_bitops_name><mode>", "*nxor<GPR:mode>_cc")
	("*nxor<mode>_cconly", "*nxor<mode>"): New insn definitions.

gcc/testsuite/ChangeLog:

2019-04-02  Andreas Krebbel  <krebbel@linux.ibm.com>

	* gcc.target/s390/arch13/bitops-1.c: New test.
	* gcc.target/s390/arch13/bitops-2.c: New test.
	* gcc.target/s390/md/andc-splitter-1.c: Add -march=z14 build
	option and adjust line numbers.
	* gcc.target/s390/md/andc-splitter-2.c: Likewise.

From-SVN: r270078
This commit is contained in:
Andreas Krebbel 2019-04-02 10:51:53 +00:00 committed by Andreas Krebbel
parent 511ea1538b
commit 4a9733f3df
8 changed files with 457 additions and 23 deletions

View File

@ -1,3 +1,21 @@
2019-04-02 Andreas Krebbel <krebbel@linux.ibm.com>
* config/s390/s390.c (s390_canonicalize_comparison): Convert
certain compares for arch13 in order to make use of the condition
code result produced by the new instructions.
(s390_rtx_costs): Adjust the costs for nnrk, nngrk, nork, nogrk,
nxrk, and nxgrk instruction patterns.
* config/s390/s390.md (ANDOR, bitops_name, inv_bitops_name)
(inv_no): Add new code iterator together with some attributes.
("*andc_split_<mode>"): Disable splitter for arch13.
("*<ANDOR:bitops_name>c<GPR:mode>_cc")
("*<ANDOR:bitops_name>c<GPR:mode>_cconly")
("*<ANDOR:bitops_name>c<GPR:mode>")
("*n<ANDOR:inv_bitops_name><GPR:mode>_cc")
("*n<ANDOR:inv_bitops_name><mode>_cconly")
("*n<ANDOR:inv_bitops_name><mode>", "*nxor<GPR:mode>_cc")
("*nxor<mode>_cconly", "*nxor<mode>"): New insn definitions.
2019-04-02 Andreas Krebbel <krebbel@linux.ibm.com>
* common/config/s390/s390-common.c (processor_flags_table): New

View File

@ -1793,6 +1793,38 @@ s390_canonicalize_comparison (int *code, rtx *op0, rtx *op1,
*op0 = XEXP (*op0, 0);
}
}
/* ~a==b -> ~(a^b)==0 ~a!=b -> ~(a^b)!=0 */
if (TARGET_ARCH13
&& (*code == EQ || *code == NE)
&& (GET_MODE (*op0) == DImode || GET_MODE (*op0) == SImode)
&& GET_CODE (*op0) == NOT)
{
machine_mode mode = GET_MODE (*op0);
*op0 = gen_rtx_XOR (mode, XEXP (*op0, 0), *op1);
*op0 = gen_rtx_NOT (mode, *op0);
*op1 = const0_rtx;
}
/* a&b == -1 -> ~a|~b == 0 a|b == -1 -> ~a&~b == 0 */
if (TARGET_ARCH13
&& (*code == EQ || *code == NE)
&& (GET_CODE (*op0) == AND || GET_CODE (*op0) == IOR)
&& (GET_MODE (*op0) == DImode || GET_MODE (*op0) == SImode)
&& CONST_INT_P (*op1)
&& *op1 == constm1_rtx)
{
machine_mode mode = GET_MODE (*op0);
rtx op00 = gen_rtx_NOT (mode, XEXP (*op0, 0));
rtx op01 = gen_rtx_NOT (mode, XEXP (*op0, 1));
if (GET_CODE (*op0) == AND)
*op0 = gen_rtx_IOR (mode, op00, op01);
else
*op0 = gen_rtx_AND (mode, op00, op01);
*op1 = const0_rtx;
}
}
@ -3516,6 +3548,21 @@ s390_rtx_costs (rtx x, machine_mode mode, int outer_code,
return true;
}
case IOR:
/* nnrk, nngrk */
if (TARGET_ARCH13
&& (mode == SImode || mode == DImode)
&& GET_CODE (XEXP (x, 0)) == NOT
&& GET_CODE (XEXP (x, 1)) == NOT)
{
*total = COSTS_N_INSNS (1);
if (!REG_P (XEXP (XEXP (x, 0), 0)))
*total += 1;
if (!REG_P (XEXP (XEXP (x, 1), 0)))
*total += 1;
return true;
}
/* risbg */
if (GET_CODE (XEXP (x, 0)) == AND
&& GET_CODE (XEXP (x, 1)) == ASHIFT
@ -3544,19 +3591,33 @@ s390_rtx_costs (rtx x, machine_mode mode, int outer_code,
*total = COSTS_N_INSNS (1);
return true;
}
*total = COSTS_N_INSNS (1);
return false;
case AND:
/* nork, nogrk */
if (TARGET_ARCH13
&& (mode == SImode || mode == DImode)
&& GET_CODE (XEXP (x, 0)) == NOT
&& GET_CODE (XEXP (x, 1)) == NOT)
{
*total = COSTS_N_INSNS (1);
if (!REG_P (XEXP (XEXP (x, 0), 0)))
*total += 1;
if (!REG_P (XEXP (XEXP (x, 1), 0)))
*total += 1;
return true;
}
/* fallthrough */
case ASHIFT:
case ASHIFTRT:
case LSHIFTRT:
case ROTATE:
case ROTATERT:
case AND:
case XOR:
case NEG:
case NOT:
*total = COSTS_N_INSNS (1);
return false;
case PLUS:
case MINUS:
*total = COSTS_N_INSNS (1);
@ -3706,6 +3767,38 @@ s390_rtx_costs (rtx x, machine_mode mode, int outer_code,
case COMPARE:
*total = COSTS_N_INSNS (1);
/* nxrk, nxgrk ~(a^b)==0 */
if (TARGET_ARCH13
&& GET_CODE (XEXP (x, 0)) == NOT
&& XEXP (x, 1) == const0_rtx
&& GET_CODE (XEXP (XEXP (x, 0), 0)) == XOR
&& (GET_MODE (XEXP (x, 0)) == SImode || GET_MODE (XEXP (x, 0)) == DImode)
&& mode == CCZmode)
{
if (!REG_P (XEXP (XEXP (XEXP (x, 0), 0), 0)))
*total += 1;
if (!REG_P (XEXP (XEXP (XEXP (x, 0), 0), 1)))
*total += 1;
return true;
}
/* nnrk, nngrk, nork, nogrk */
if (TARGET_ARCH13
&& (GET_CODE (XEXP (x, 0)) == AND || GET_CODE (XEXP (x, 0)) == IOR)
&& XEXP (x, 1) == const0_rtx
&& (GET_MODE (XEXP (x, 0)) == SImode || GET_MODE (XEXP (x, 0)) == DImode)
&& GET_CODE (XEXP (XEXP (x, 0), 0)) == NOT
&& GET_CODE (XEXP (XEXP (x, 0), 1)) == NOT
&& mode == CCZmode)
{
if (!REG_P (XEXP (XEXP (XEXP (x, 0), 0), 0)))
*total += 1;
if (!REG_P (XEXP (XEXP (XEXP (x, 0), 1), 0)))
*total += 1;
return true;
}
if (GET_CODE (XEXP (x, 0)) == AND
&& GET_CODE (XEXP (x, 1)) == CONST_INT
&& GET_CODE (XEXP (XEXP (x, 0), 1)) == CONST_INT)

View File

@ -669,6 +669,12 @@
;; This iterator allows r[ox]sbg to be defined with the same template
(define_code_iterator IXOR [ior xor])
;; This is used for merging the nand/nor and and/or with complement patterns
(define_code_iterator ANDOR [and ior])
(define_code_attr bitops_name [(and "and") (ior "or")])
(define_code_attr inv_bitops_name [(and "or") (ior "and")])
(define_code_attr inv_no [(and "o") (ior "n")])
;; This iterator is used to expand the patterns for the nearest
;; integer functions.
(define_int_iterator FPINT [UNSPEC_FPINT_FLOOR UNSPEC_FPINT_BTRUNC
@ -7534,7 +7540,8 @@
(and:GPR (not:GPR (match_operand:GPR 1 "nonimmediate_operand" ""))
(match_operand:GPR 2 "general_operand" "")))
(clobber (reg:CC CC_REGNUM))]
"! reload_completed
"!TARGET_ARCH13
&& ! reload_completed
&& (GET_CODE (operands[0]) != MEM
/* Ensure that s390_logical_operator_ok_p will succeed even
on the split xor if (b & a) is stored into a pseudo. */
@ -7876,6 +7883,87 @@
[(set_attr "op_type" "RR,SI,SS")
(set_attr "z10prop" "z10_super_E1,z10_super,*")])
;
; And/Or with complement
;
; ncrk, ncgrk, ocrk, ocgrk
(define_insn "*<ANDOR:bitops_name>c<GPR:mode>_cc"
[(set (reg CC_REGNUM)
(compare
(ANDOR:GPR (not:GPR (match_operand:GPR 1 "register_operand" "d"))
(match_operand:GPR 2 "register_operand" "d"))
(const_int 0)))
(set (match_operand:GPR 0 "register_operand" "=d")
(ANDOR:GPR (not:GPR (match_dup 1))
(match_dup 2)))]
"TARGET_ARCH13 && s390_match_ccmode(insn, CCTmode)"
"<ANDOR:noxa>c<GPR:g>rk\t%0,%2,%1"
[(set_attr "op_type" "RRF")])
; ncrk, ncgrk, ocrk, ocgrk
(define_insn "*<ANDOR:bitops_name>c<GPR:mode>_cconly"
[(set (reg CC_REGNUM)
(compare
(ANDOR:GPR (not:GPR (match_operand:GPR 1 "register_operand" "d"))
(match_operand:GPR 2 "register_operand" "d"))
(const_int 0)))
(clobber (match_scratch:GPR 0 "=d"))]
"TARGET_ARCH13 && s390_match_ccmode(insn, CCTmode)"
"<ANDOR:noxa>c<GPR:g>rk\t%0,%2,%1"
[(set_attr "op_type" "RRF")])
; ncrk, ncgrk, ocrk, ocgrk
(define_insn "*<ANDOR:bitops_name>c<GPR:mode>"
[(set (match_operand:GPR 0 "register_operand" "=d")
(ANDOR:GPR (not:GPR (match_operand:GPR 1 "register_operand" "d"))
(match_operand:GPR 2 "register_operand" "d")))
(clobber (reg:CC CC_REGNUM))]
"TARGET_ARCH13"
"<ANDOR:noxa>c<GPR:g>rk\t%0,%2,%1"
[(set_attr "op_type" "RRF")])
;
;- Nand/Nor instructions.
;
; nnrk, nngrk, nork, nogrk
(define_insn "*n<ANDOR:inv_bitops_name><GPR:mode>_cc"
[(set (reg CC_REGNUM)
(compare
(ANDOR:GPR (not:GPR (match_operand:GPR 1 "register_operand" "d"))
(not:GPR (match_operand:GPR 2 "register_operand" "d")))
(const_int 0)))
(set (match_operand:GPR 0 "register_operand" "=d")
(ANDOR:GPR (not:GPR (match_dup 1))
(not:GPR (match_dup 2))))]
"TARGET_ARCH13 && s390_match_ccmode(insn, CCTmode)"
"n<ANDOR:inv_no><GPR:g>rk\t%0,%1,%2"
[(set_attr "op_type" "RRF")])
; nnrk, nngrk, nork, nogrk
(define_insn "*n<ANDOR:inv_bitops_name><mode>_cconly"
[(set (reg CC_REGNUM)
(compare
(ANDOR:GPR (not:GPR (match_operand:GPR 1 "register_operand" "d"))
(not:GPR (match_operand:GPR 2 "register_operand" "d")))
(const_int 0)))
(clobber (match_scratch:GPR 0 "=d"))]
"TARGET_ARCH13 && s390_match_ccmode(insn, CCTmode)"
"n<ANDOR:inv_no><GPR:g>rk\t%0,%1,%2"
[(set_attr "op_type" "RRF")])
; nnrk, nngrk, nork, nogrk
(define_insn "*n<ANDOR:inv_bitops_name><mode>"
[(set (match_operand:GPR 0 "register_operand" "=d")
(ANDOR:GPR (not:GPR (match_operand:GPR 1 "register_operand" "d"))
(not:GPR (match_operand:GPR 2 "register_operand" "d"))))
(clobber (reg:CC CC_REGNUM))]
"TARGET_ARCH13"
"n<ANDOR:inv_no><GPR:g>rk\t%0,%1,%2"
[(set_attr "op_type" "RRF")])
;
; Block inclusive or (OC) patterns.
;
@ -8241,6 +8329,45 @@
"operands[4] = gen_rtx_MEM (BLKmode, XEXP (operands[0], 0));
operands[5] = GEN_INT (INTVAL (operands[1]) + INTVAL (operands[3]));")
;
;- Nxor instructions.
;
; nxrk, nxgrk
(define_insn "*nxor<GPR:mode>_cc"
[(set (reg CC_REGNUM)
(compare
(not:GPR (xor:GPR (match_operand:GPR 1 "register_operand" "d")
(match_operand:GPR 2 "register_operand" "d")))
(const_int 0)))
(set (match_operand:GPR 0 "register_operand" "=d")
(xor:GPR (not:GPR (match_dup 1))
(match_dup 2)))]
"TARGET_ARCH13 && s390_match_ccmode(insn, CCTmode)"
"nx<GPR:g>rk\t%0,%1,%2"
[(set_attr "op_type" "RRF")])
; nxrk, nxgrk
(define_insn "*nxor<mode>_cconly"
[(set (reg CC_REGNUM)
(compare
(not:GPR (xor:GPR (match_operand:GPR 1 "register_operand" "d")
(match_operand:GPR 2 "register_operand" "d")))
(const_int 0)))
(clobber (match_scratch:GPR 0 "=d"))]
"TARGET_ARCH13 && s390_match_ccmode(insn, CCTmode)"
"nx<GPR:g>rk\t%0,%1,%2"
[(set_attr "op_type" "RRF")])
; nxrk, nxgrk
(define_insn "*nxor<mode>"
[(set (match_operand:GPR 0 "register_operand" "=d")
(not:GPR (xor:GPR (match_operand:GPR 1 "register_operand" "d")
(match_operand:GPR 2 "register_operand" "d"))))
(clobber (reg:CC CC_REGNUM))]
"TARGET_ARCH13"
"nx<GPR:g>rk\t%0,%1,%2"
[(set_attr "op_type" "RRF")])
;;
;;- Negate instructions.

View File

@ -1,3 +1,11 @@
2019-04-02 Andreas Krebbel <krebbel@linux.ibm.com>
* gcc.target/s390/arch13/bitops-1.c: New test.
* gcc.target/s390/arch13/bitops-2.c: New test.
* gcc.target/s390/md/andc-splitter-1.c: Add -march=z14 build
option and adjust line numbers.
* gcc.target/s390/md/andc-splitter-2.c: Likewise.
2019-04-02 Andreas Krebbel <krebbel@linux.ibm.com>
* gcc.target/s390/s390.exp: Run tests in arch13 subdir.

View File

@ -0,0 +1,91 @@
/* { dg-compile } */
/* and with complement */
int
ncrk (int a, int b)
{
return a & ~b;
}
/* { dg-final { scan-assembler-times "\tncrk\t" 1 } } */
long long
ncgrk (long long a, long long b)
{
return a & ~b;
}
/* { dg-final { scan-assembler-times "\tncgrk\t" 1 } } */
/* or with complement */
int
ocrk (int a, int b)
{
return a | ~b;
}
/* { dg-final { scan-assembler-times "\tocrk\t" 1 } } */
long long
ocgrk (long long a, long long b)
{
return a | ~b;
}
/* { dg-final { scan-assembler-times "\tocgrk\t" 1 } } */
/* nand */
int
nnrk (int a, int b)
{
return ~(a & b);
}
/* { dg-final { scan-assembler-times "\tnnrk\t" 1 } } */
long long
nngrk (long long a, long long b)
{
return ~(a & b);
}
/* { dg-final { scan-assembler-times "\tnngrk\t" 1 } } */
/* nor */
int
nork (int a, int b)
{
return ~(a | b);
}
/* { dg-final { scan-assembler-times "\tnork\t" 1 } } */
long long
nogrk (long long a, long long b)
{
return ~(a | b);
}
/* { dg-final { scan-assembler-times "\tnogrk\t" 1 } } */
/* nxor */
int
nxrk (int a, int b)
{
return ~(a ^ b);
}
/* { dg-final { scan-assembler-times "\tnxrk\t" 1 } } */
long long
nxgrk (long long a, long long b)
{
return ~(a ^ b);
}
/* { dg-final { scan-assembler-times "\tnxgrk\t" 1 } } */

View File

@ -0,0 +1,93 @@
/* { dg-compile } */
/* Check if the instruction are being used also for compares. */
/* and with complement */
int
ncrk (int a, int b)
{
return (a & ~b) ? 23 : 42;
}
/* { dg-final { scan-assembler-times "\tncrk\t" 1 } } */
int
ncgrk (long long a, long long b)
{
return (a & ~b) ? 23 : 42;
}
/* { dg-final { scan-assembler-times "\tncgrk\t" 1 } } */
/* or with complement */
int
ocrk (int a, int b)
{
return (a | ~b) ? 23 : 42;
}
/* { dg-final { scan-assembler-times "\tocrk\t" 1 } } */
int
ocgrk (long long a, long long b)
{
return (a | ~b) ? 23 : 42;
}
/* { dg-final { scan-assembler-times "\tocgrk\t" 1 } } */
/* nand */
int
nnrk (int a, int b)
{
return ~(a & b) ? 23 : 42;
}
/* { dg-final { scan-assembler-times "\tnnrk\t" 1 } } */
int
nngrk (long long a, long long b)
{
return ~(a & b) ? 23 : 42;
}
/* { dg-final { scan-assembler-times "\tnngrk\t" 1 } } */
/* nor */
int
nork (int a, int b)
{
return ~(a | b);
}
/* { dg-final { scan-assembler-times "\tnork\t" 1 } } */
int
nogrk (long long a, long long b)
{
return ~(a | b) ? 23 : 42;
}
/* { dg-final { scan-assembler-times "\tnogrk\t" 1 } } */
/* nxor */
int
nxrk (int a, int b)
{
return ~(a ^ b) ? 23 : 42;
}
/* { dg-final { scan-assembler-times "\tnxrk\t" 1 } } */
int
nxgrk (long long a, long long b)
{
return ~(a ^ b) ? 23 : 42;
}
/* { dg-final { scan-assembler-times "\tnxgrk\t" 1 } } */

View File

@ -1,7 +1,9 @@
/* Machine description pattern tests. */
/* { dg-do compile { target { lp64 } } } */
/* { dg-options "-mzarch -save-temps -dP" } */
/* Starting with arch13 the and with complement instruction is
available and the splitter is disabled. */
/* { dg-options "-march=z14 -mzarch -save-temps -dP" } */
/* { dg-do run { target { lp64 && s390_useable_hw } } } */
/* Skip test if -O0 is present on the command line:
@ -14,26 +16,26 @@
__attribute__ ((noinline))
unsigned long andc_vv(unsigned long a, unsigned long b)
{ return ~b & a; }
/* { dg-final { scan-assembler ":16:.\* \{\\*anddi3\}" } } */
/* { dg-final { scan-assembler ":16:.\* \{\\*xordi3\}" } } */
/* { dg-final { scan-assembler ":18:.\* \{\\*anddi3\}" } } */
/* { dg-final { scan-assembler ":18:.\* \{\\*xordi3\}" } } */
__attribute__ ((noinline))
unsigned long andc_pv(unsigned long *a, unsigned long b)
{ return ~b & *a; }
/* { dg-final { scan-assembler ":22:.\* \{\\*anddi3\}" } } */
/* { dg-final { scan-assembler ":22:.\* \{\\*xordi3\}" } } */
/* { dg-final { scan-assembler ":24:.\* \{\\*anddi3\}" } } */
/* { dg-final { scan-assembler ":24:.\* \{\\*xordi3\}" } } */
__attribute__ ((noinline))
unsigned long andc_vp(unsigned long a, unsigned long *b)
{ return ~*b & a; }
/* { dg-final { scan-assembler ":28:.\* \{\\*anddi3\}" } } */
/* { dg-final { scan-assembler ":28:.\* \{\\*xordi3\}" } } */
/* { dg-final { scan-assembler ":30:.\* \{\\*anddi3\}" } } */
/* { dg-final { scan-assembler ":30:.\* \{\\*xordi3\}" } } */
__attribute__ ((noinline))
unsigned long andc_pp(unsigned long *a, unsigned long *b)
{ return ~*b & *a; }
/* { dg-final { scan-assembler ":34:.\* \{\\*anddi3\}" } } */
/* { dg-final { scan-assembler ":34:.\* \{\\*xordi3\}" } } */
/* { dg-final { scan-assembler ":36:.\* \{\\*anddi3\}" } } */
/* { dg-final { scan-assembler ":36:.\* \{\\*xordi3\}" } } */
/* { dg-final { scan-assembler-times "\tngr\?k\?\t" 4 } } */
/* { dg-final { scan-assembler-times "\txgr\?\t" 4 } } */

View File

@ -1,7 +1,9 @@
/* Machine description pattern tests. */
/* { dg-do compile } */
/* { dg-options "-save-temps -dP" } */
/* Starting with arch13 the and with complement instruction is
available and the splitter is disabled. */
/* { dg-options "-march=z14 -save-temps -dP" } */
/* { dg-do run { target { s390_useable_hw } } } */
/* Skip test if -O0 is present on the command line:
@ -14,26 +16,26 @@
__attribute__ ((noinline))
unsigned int andc_vv(unsigned int a, unsigned int b)
{ return ~b & a; }
/* { dg-final { scan-assembler ":16:.\* \{\\*andsi3_\(esa\|zarch\)\}" } } */
/* { dg-final { scan-assembler ":16:.\* \{\\*xorsi3\}" } } */
/* { dg-final { scan-assembler ":18:.\* \{\\*andsi3_\(esa\|zarch\)\}" } } */
/* { dg-final { scan-assembler ":18:.\* \{\\*xorsi3\}" } } */
__attribute__ ((noinline))
unsigned int andc_pv(unsigned int *a, unsigned int b)
{ return ~b & *a; }
/* { dg-final { scan-assembler ":22:.\* \{\\*andsi3_\(esa\|zarch\)\}" } } */
/* { dg-final { scan-assembler ":22:.\* \{\\*xorsi3\}" } } */
/* { dg-final { scan-assembler ":24:.\* \{\\*andsi3_\(esa\|zarch\)\}" } } */
/* { dg-final { scan-assembler ":24:.\* \{\\*xorsi3\}" } } */
__attribute__ ((noinline))
unsigned int andc_vp(unsigned int a, unsigned int *b)
{ return ~*b & a; }
/* { dg-final { scan-assembler ":28:.\* \{\\*andsi3_\(esa\|zarch\)\}" } } */
/* { dg-final { scan-assembler ":28:.\* \{\\*xorsi3\}" } } */
/* { dg-final { scan-assembler ":30:.\* \{\\*andsi3_\(esa\|zarch\)\}" } } */
/* { dg-final { scan-assembler ":30:.\* \{\\*xorsi3\}" } } */
__attribute__ ((noinline))
unsigned int andc_pp(unsigned int *a, unsigned int *b)
{ return ~*b & *a; }
/* { dg-final { scan-assembler ":34:.\* \{\\*andsi3_\(esa\|zarch\)\}" } } */
/* { dg-final { scan-assembler ":34:.\* \{\\*xorsi3\}" } } */
/* { dg-final { scan-assembler ":36:.\* \{\\*andsi3_\(esa\|zarch\)\}" } } */
/* { dg-final { scan-assembler ":36:.\* \{\\*xorsi3\}" } } */
/* { dg-final { scan-assembler-times "\tnr\?k\?\t" 4 } } */
/* { dg-final { scan-assembler-times "\txr\?k\?\t" 4 } } */