Skip to content
Snippets Groups Projects
Commit 32462550 authored by Philipp Tomsich's avatar Philipp Tomsich
Browse files

RISC-V: Split "(a & (1UL << bitno)) ? 0 : -1" to bext + addi

For a straightforward application of bext for the following function
  long bext64(long a, char bitno)
  {
    return (a & (1UL << bitno)) ? 0 : -1;
  }
we generate
	srl	a0,a0,a1	# 7	[c=4 l=4]  lshrdi3
	andi	a0,a0,1	# 8	[c=4 l=4]  anddi3/1
	addi	a0,a0,-1	# 14	[c=4 l=4]  adddi3/1
due to the following failed match at combine time:
  (set (reg:DI 82)
       (zero_extract:DI (reg:DI 83)
            (const_int 1 [0x1])
            (reg:DI 84)))

The existing pattern for bext requires the 3rd argument to
zero_extract to be a QImode register wrapped in a zero_extension.
This adds an additional pattern that allows an Xmode argument.

With this change, the testcase compiles to
	bext	a0,a0,a1	# 8	[c=4 l=4]  *bextdi
	addi	a0,a0,-1	# 14	[c=4 l=4]  adddi3/1

gcc/ChangeLog:

	* config/riscv/bitmanip.md (*bext<mode>): Add an additional
	pattern that allows the 3rd argument to zero_extract to be
	an Xmode register operand.

gcc/testsuite/ChangeLog:

	* gcc.target/riscv/zbs-bext.c: Add testcases.
	* gcc.target/riscv/zbs-bexti.c: Add testcases.
parent e91d5145
No related branches found
No related tags found
No related merge requests found
......@@ -394,6 +394,18 @@
"bext\t%0,%1,%2"
[(set_attr "type" "bitmanip")])
;; When performing `(a & (1UL << bitno)) ? 0 : -1` the combiner
;; usually has the `bitno` typed as X-mode (i.e. no further
;; zero-extension is performed around the bitno).
(define_insn "*bext<mode>"
[(set (match_operand:X 0 "register_operand" "=r")
(zero_extract:X (match_operand:X 1 "register_operand" "r")
(const_int 1)
(match_operand:X 2 "register_operand" "r")))]
"TARGET_ZBS"
"bext\t%0,%1,%2"
[(set_attr "type" "bitmanip")])
(define_insn "*bexti"
[(set (match_operand:X 0 "register_operand" "=r")
(zero_extract:X (match_operand:X 1 "register_operand" "r")
......
/* { dg-do compile } */
/* { dg-options "-march=rv64gc_zbs -mabi=lp64" } */
/* { dg-skip-if "" { *-*-* } { "-O0" } } */
/* { dg-skip-if "" { *-*-* } { "-O0" "-Og" } } */
/* bext */
long
......@@ -16,6 +16,23 @@ foo1 (long i)
return 1L & (i >> 20);
}
long bext64_1(long a, char bitno)
{
return (a & (1UL << bitno)) ? 1 : 0;
}
long bext64_2(long a, char bitno)
{
return (a & (1UL << bitno)) ? 0 : -1;
}
long bext64_3(long a, char bitno)
{
return (a & (1UL << bitno)) ? -1 : 0;
}
/* { dg-final { scan-assembler-times "bexti\t" 1 } } */
/* { dg-final { scan-assembler-times "bext\t" 1 } } */
/* { dg-final { scan-assembler-not "andi" } } */
/* { dg-final { scan-assembler-times "bext\t" 4 } } */
/* { dg-final { scan-assembler-times "addi\t" 1 } } */
/* { dg-final { scan-assembler-times "neg\t" 1 } } */
/* { dg-final { scan-assembler-not "andi" } } */
\ No newline at end of file
/* { dg-do compile } */
/* { dg-options "-march=rv64gc_zbs -mabi=lp64" } */
/* { dg-skip-if "" { *-*-* } { "-O0" "-Og" } } */
/* bexti */
#define BIT_NO 21
long bexti64_1(long a, char bitno)
{
return (a & (1UL << BIT_NO)) ? 1 : 0;
}
long bexti64_2(long a, char bitno)
{
return (a & (1UL << BIT_NO)) ? 0 : -1;
}
long bexti64_3(long a, char bitno)
{
return (a & (1UL << BIT_NO)) ? -1 : 0;
}
/* { dg-final { scan-assembler-times "bexti\t" 3 } } */
/* { dg-final { scan-assembler-times "addi\t" 1 } } */
/* { dg-final { scan-assembler-times "neg\t" 1 } } */
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment