* [PATCH 3/5][Arm] New pattern for CSINC instructions
@ 2020-08-04 16:13 Omar Tahir
2020-08-06 11:40 ` Kyrylo Tkachov
0 siblings, 1 reply; 4+ messages in thread
From: Omar Tahir @ 2020-08-04 16:13 UTC (permalink / raw)
To: Kyrylo Tkachov, nickc, Ramana Radhakrishnan, Richard Earnshaw,
gcc-patches
[-- Attachment #1: Type: text/plain, Size: 2653 bytes --]
This patch adds a new pattern, *thumb2_csinc, for generating CSINC
instructions. It also modifies an existing pattern, *thumb2_cond_arith, to
output CINC when the operation is an addition and TARGET_COND_ARITH is true.
Regression tested on arm-none-eabi.
2020-07-30: Sudakshina Das <sudi.das@arm.com>
Omar Tahir <omar.tahir@arm.com>
* config/arm/thumb2.md (*thumb2_csinc): New.
(*thumb2_cond_arith): Generate CINC where possible.
gcc/testsuite/ChangeLog:
2020-07-30: Sudakshina Das <sudi.das@arm.com>
Omar Tahir <omar.tahir@arm.com>
* gcc.target/arm/csinc-1.c: New test.
diff --git a/gcc/config/arm/thumb2.md b/gcc/config/arm/thumb2.md
index 0b00aef7ef7..79cf684e5cb 100644
--- a/gcc/config/arm/thumb2.md
+++ b/gcc/config/arm/thumb2.md
@@ -743,6 +743,9 @@
if (GET_CODE (operands[4]) == LT && operands[3] == const0_rtx)
return \"%i5\\t%0, %1, %2, lsr #31\";
+ if (GET_CODE (operands[5]) == PLUS && TARGET_COND_ARITH)
+ return \"cinc\\t%0, %1, %d4\";
+
output_asm_insn (\"cmp\\t%2, %3\", operands);
if (GET_CODE (operands[5]) == AND)
{
@@ -952,6 +955,21 @@
(set_attr "predicable" "no")]
)
+(define_insn "*thumb2_csinc"
+ [(set (match_operand:SI 0 "arm_general_register_operand" "=r, r")
+ (if_then_else:SI
+ (match_operand 1 "arm_comparison_operation" "")
+ (plus:SI (match_operand:SI 2 "arm_general_register_operand" "r, r")
+ (const_int 1))
+ (match_operand:SI 3 "reg_or_zero_operand" "r, Z")))]
+ "TARGET_COND_ARITH"
+ "@
+ csinc\\t%0, %3, %2, %D1
+ csinc\\t%0, zr, %2, %D1"
+ [(set_attr "type" "csel")
+ (set_attr "predicable" "no")]
+)
+
(define_insn "*thumb2_movcond"
[(set (match_operand:SI 0 "s_register_operand" "=Ts,Ts,Ts")
(if_then_else:SI
diff --git a/gcc/testsuite/gcc.target/arm/csinc-1.c b/gcc/testsuite/gcc.target/arm/csinc-1.c
new file mode 100644
index 00000000000..b9928493862
--- /dev/null
+++ b/gcc/testsuite/gcc.target/arm/csinc-1.c
@@ -0,0 +1,23 @@
+/* { dg-do compile } */
+/* { dg-require-effective-target arm_arch_v8_1m_main_ok } */
+/* { dg-options "-O2 -march=armv8.1-m.main" } */
+
+int
+test_csinc32_condasn1(int w0, int w1, int w2, int w3)
+{
+ int w4;
+
+ /* { dg-final { scan-assembler "csinc\tr\[0-9\]*.*ne" } } */
+ w4 = (w0 == w1) ? (w2 + 1) : w3;
+ return w4;
+}
+
+int
+test_csinc32_condasn2(int w0, int w1, int w2, int w3)
+{
+ int w4;
+
+ /* { dg-final { scan-assembler "csinc\tr\[0-9\]*.*eq" } } */
+ w4 = (w0 == w1) ? w3 : (w2 + 1);
+ return w4;
+}
[-- Attachment #2: csel_3.patch --]
[-- Type: application/octet-stream, Size: 1910 bytes --]
diff --git a/gcc/config/arm/thumb2.md b/gcc/config/arm/thumb2.md
index 0b00aef7ef7..79cf684e5cb 100644
--- a/gcc/config/arm/thumb2.md
+++ b/gcc/config/arm/thumb2.md
@@ -743,6 +743,9 @@
if (GET_CODE (operands[4]) == LT && operands[3] == const0_rtx)
return \"%i5\\t%0, %1, %2, lsr #31\";
+ if (GET_CODE (operands[5]) == PLUS && TARGET_COND_ARITH)
+ return \"cinc\\t%0, %1, %d4\";
+
output_asm_insn (\"cmp\\t%2, %3\", operands);
if (GET_CODE (operands[5]) == AND)
{
@@ -952,6 +955,21 @@
(set_attr "predicable" "no")]
)
+(define_insn "*thumb2_csinc"
+ [(set (match_operand:SI 0 "arm_general_register_operand" "=r, r")
+ (if_then_else:SI
+ (match_operand 1 "arm_comparison_operation" "")
+ (plus:SI (match_operand:SI 2 "arm_general_register_operand" "r, r")
+ (const_int 1))
+ (match_operand:SI 3 "reg_or_zero_operand" "r, Z")))]
+ "TARGET_COND_ARITH"
+ "@
+ csinc\\t%0, %3, %2, %D1
+ csinc\\t%0, zr, %2, %D1"
+ [(set_attr "type" "csel")
+ (set_attr "predicable" "no")]
+)
+
(define_insn "*thumb2_movcond"
[(set (match_operand:SI 0 "s_register_operand" "=Ts,Ts,Ts")
(if_then_else:SI
diff --git a/gcc/testsuite/gcc.target/arm/csinc-1.c b/gcc/testsuite/gcc.target/arm/csinc-1.c
new file mode 100644
index 00000000000..b9928493862
--- /dev/null
+++ b/gcc/testsuite/gcc.target/arm/csinc-1.c
@@ -0,0 +1,23 @@
+/* { dg-do compile } */
+/* { dg-require-effective-target arm_arch_v8_1m_main_ok } */
+/* { dg-options "-O2 -march=armv8.1-m.main" } */
+
+int
+test_csinc32_condasn1(int w0, int w1, int w2, int w3)
+{
+ int w4;
+
+ /* { dg-final { scan-assembler "csinc\tr\[0-9\]*.*ne" } } */
+ w4 = (w0 == w1) ? (w2 + 1) : w3;
+ return w4;
+}
+
+int
+test_csinc32_condasn2(int w0, int w1, int w2, int w3)
+{
+ int w4;
+
+ /* { dg-final { scan-assembler "csinc\tr\[0-9\]*.*eq" } } */
+ w4 = (w0 == w1) ? w3 : (w2 + 1);
+ return w4;
+}
^ permalink raw reply [flat|nested] 4+ messages in thread
* RE: [PATCH 3/5][Arm] New pattern for CSINC instructions
2020-08-04 16:13 [PATCH 3/5][Arm] New pattern for CSINC instructions Omar Tahir
@ 2020-08-06 11:40 ` Kyrylo Tkachov
2020-08-06 12:02 ` Omar Tahir
0 siblings, 1 reply; 4+ messages in thread
From: Kyrylo Tkachov @ 2020-08-06 11:40 UTC (permalink / raw)
To: Omar Tahir, nickc, Ramana Radhakrishnan, Richard Earnshaw, gcc-patches
Hi Omar,
From: Omar Tahir <Omar.Tahir@arm.com>
Sent: 04 August 2020 17:13
To: Kyrylo Tkachov <Kyrylo.Tkachov@arm.com>; nickc@redhat.com; Ramana Radhakrishnan <Ramana.Radhakrishnan@arm.com>; Richard Earnshaw <Richard.Earnshaw@arm.com>; gcc-patches@gcc.gnu.org
Subject: [PATCH 3/5][Arm] New pattern for CSINC instructions
This patch adds a new pattern, *thumb2_csinc, for generating CSINC
instructions. It also modifies an existing pattern, *thumb2_cond_arith, to
output CINC when the operation is an addition and TARGET_COND_ARITH is true.
Regression tested on arm-none-eabi.
2020-07-30: Sudakshina Das <mailto:sudi.das@arm.com>
Omar Tahir <mailto:omar.tahir@arm.com>
* config/arm/thumb2.md (*thumb2_csinc): New.
(*thumb2_cond_arith): Generate CINC where possible.
gcc/testsuite/ChangeLog:
2020-07-30: Sudakshina Das <mailto:sudi.das@arm.com>
Omar Tahir <mailto:omar.tahir@arm.com>
* gcc.target/arm/csinc-1.c: New test.
diff --git a/gcc/config/arm/thumb2.md b/gcc/config/arm/thumb2.md
index 0b00aef7ef7..79cf684e5cb 100644
--- a/gcc/config/arm/thumb2.md
+++ b/gcc/config/arm/thumb2.md
@@ -743,6 +743,9 @@
if (GET_CODE (operands[4]) == LT && operands[3] == const0_rtx)
return \"%i5\\t%0, %1, %2, lsr #31\";
+ if (GET_CODE (operands[5]) == PLUS && TARGET_COND_ARITH)
+ return \"cinc\\t%0, %1, %d4\";
+
output_asm_insn (\"cmp\\t%2, %3\", operands);
Hmmm, this looks wrong. The pattern needs to perform the comparison (setting the CC reg) as well as do the conditional increment.
Emitting a cinc without a cmp won't set the CC flags.
Also, cinc increments only by 1, whereas the "arm_rhs_operand" predicate accepts a wider variety of immediates, so just checking for GET_CODE (operands[5]) == PLUS isn't enough.
Thanks,
Kyrill
if (GET_CODE (operands[5]) == AND)
{
@@ -952,6 +955,21 @@
(set_attr "predicable" "no")]
)
+(define_insn "*thumb2_csinc"
+ [(set (match_operand:SI 0 "arm_general_register_operand" "=r, r")
+ (if_then_else:SI
+ (match_operand 1 "arm_comparison_operation" "")
+ (plus:SI (match_operand:SI 2 "arm_general_register_operand" "r, r")
+ (const_int 1))
+ (match_operand:SI 3 "reg_or_zero_operand" "r, Z")))]
+ "TARGET_COND_ARITH"
+ "@
+ csinc\\t%0, %3, %2, %D1
+ csinc\\t%0, zr, %2, %D1"
+ [(set_attr "type" "csel")
+ (set_attr "predicable" "no")]
+)
+
(define_insn "*thumb2_movcond"
[(set (match_operand:SI 0 "s_register_operand" "=Ts,Ts,Ts")
(if_then_else:SI
diff --git a/gcc/testsuite/gcc.target/arm/csinc-1.c b/gcc/testsuite/gcc.target/arm/csinc-1.c
new file mode 100644
index 00000000000..b9928493862
--- /dev/null
+++ b/gcc/testsuite/gcc.target/arm/csinc-1.c
@@ -0,0 +1,23 @@
+/* { dg-do compile } */
+/* { dg-require-effective-target arm_arch_v8_1m_main_ok } */
+/* { dg-options "-O2 -march=armv8.1-m.main" } */
+
+int
+test_csinc32_condasn1(int w0, int w1, int w2, int w3)
+{
+ int w4;
+
+ /* { dg-final { scan-assembler "csinc\tr\[0-9\]*.*ne" } } */
+ w4 = (w0 == w1) ? (w2 + 1) : w3;
+ return w4;
+}
+
+int
+test_csinc32_condasn2(int w0, int w1, int w2, int w3)
+{
+ int w4;
+
+ /* { dg-final { scan-assembler "csinc\tr\[0-9\]*.*eq" } } */
+ w4 = (w0 == w1) ? w3 : (w2 + 1);
+ return w4;
+}
^ permalink raw reply [flat|nested] 4+ messages in thread
* RE: [PATCH 3/5][Arm] New pattern for CSINC instructions
2020-08-06 11:40 ` Kyrylo Tkachov
@ 2020-08-06 12:02 ` Omar Tahir
2020-08-07 7:52 ` Kyrylo Tkachov
0 siblings, 1 reply; 4+ messages in thread
From: Omar Tahir @ 2020-08-06 12:02 UTC (permalink / raw)
To: Kyrylo Tkachov, nickc, Ramana Radhakrishnan, Richard Earnshaw,
gcc-patches
> Hi Omar,
>
> diff --git a/gcc/config/arm/thumb2.md b/gcc/config/arm/thumb2.md
> index 0b00aef7ef7..79cf684e5cb 100644
> --- a/gcc/config/arm/thumb2.md
> +++ b/gcc/config/arm/thumb2.md
> @@ -743,6 +743,9 @@
> if (GET_CODE (operands[4]) == LT && operands[3] == const0_rtx)
> return \"%i5\\t%0, %1, %2, lsr #31\";
>
> + if (GET_CODE (operands[5]) == PLUS && TARGET_COND_ARITH)
> + return \"cinc\\t%0, %1, %d4\";
> +
> output_asm_insn (\"cmp\\t%2, %3\", operands);
>
>
> Hmmm, this looks wrong. The pattern needs to perform the comparison (setting the CC reg) as well as do the conditional increment.
> Emitting a cinc without a cmp won't set the CC flags.
> Also, cinc increments only by 1, whereas the "arm_rhs_operand" predicate accepts a wider variety of immediates, so just checking for GET_CODE (operands[5]) == PLUS isn't enough.
>
> Thanks,
> Kyrill
>
My bad, the following line
output_asm_insn (\"cmp\\t%2, %3\", operands);
should be before my change rather than after, that will generate the cmp needed.
As for the predicate accepting other immediates, I don't think that's an issue. From what I understand, the pattern represents
r0 = f5 (f4 (r2, r3), r1)
where f5 is a shiftable operator and f4 is a comparison operator. For simplicity let's just assume f4 is ==. Then we have
r0 = f5 (r1, r2 == r3)
If f5 is PLUS then we get
r0 = r1 + (r2 == r3)
which is
r0 = (r2 == r3) ? r1 + 1 : r1
i.e. cmp r2, r3 \\ cinc r0, r1, eq. Since all comparisons return either zero (comparison failed) or 1 (comparison passed) a cinc should always work as long as the shiftable operator is PLUS.
Operand 3 being an "arm_rhs_operand" shouldn't matter since it's just being compared to operand 2 and returning a 0 or 1.
Thanks,
Omar
^ permalink raw reply [flat|nested] 4+ messages in thread
* RE: [PATCH 3/5][Arm] New pattern for CSINC instructions
2020-08-06 12:02 ` Omar Tahir
@ 2020-08-07 7:52 ` Kyrylo Tkachov
0 siblings, 0 replies; 4+ messages in thread
From: Kyrylo Tkachov @ 2020-08-07 7:52 UTC (permalink / raw)
To: Omar Tahir, nickc, Ramana Radhakrishnan, Richard Earnshaw, gcc-patches
> -----Original Message-----
> From: Omar Tahir <Omar.Tahir@arm.com>
> Sent: 06 August 2020 13:02
> To: Kyrylo Tkachov <Kyrylo.Tkachov@arm.com>; nickc@redhat.com;
> Ramana Radhakrishnan <Ramana.Radhakrishnan@arm.com>; Richard
> Earnshaw <Richard.Earnshaw@arm.com>; gcc-patches@gcc.gnu.org
> Subject: RE: [PATCH 3/5][Arm] New pattern for CSINC instructions
>
> > Hi Omar,
> >
> > diff --git a/gcc/config/arm/thumb2.md b/gcc/config/arm/thumb2.md
> > index 0b00aef7ef7..79cf684e5cb 100644
> > --- a/gcc/config/arm/thumb2.md
> > +++ b/gcc/config/arm/thumb2.md
> > @@ -743,6 +743,9 @@
> > if (GET_CODE (operands[4]) == LT && operands[3] == const0_rtx)
> > return \"%i5\\t%0, %1, %2, lsr #31\";
> >
> > + if (GET_CODE (operands[5]) == PLUS && TARGET_COND_ARITH)
> > + return \"cinc\\t%0, %1, %d4\";
> > +
> > output_asm_insn (\"cmp\\t%2, %3\", operands);
> >
> >
> > Hmmm, this looks wrong. The pattern needs to perform the comparison
> (setting the CC reg) as well as do the conditional increment.
> > Emitting a cinc without a cmp won't set the CC flags.
> > Also, cinc increments only by 1, whereas the "arm_rhs_operand" predicate
> accepts a wider variety of immediates, so just checking for GET_CODE
> (operands[5]) == PLUS isn't enough.
> >
> > Thanks,
> > Kyrill
> >
>
> My bad, the following line
>
> output_asm_insn (\"cmp\\t%2, %3\", operands);
>
> should be before my change rather than after, that will generate the cmp
> needed.
>
> As for the predicate accepting other immediates, I don't think that's an issue.
> From what I understand, the pattern represents
>
> r0 = f5 (f4 (r2, r3), r1)
>
> where f5 is a shiftable operator and f4 is a comparison operator. For
> simplicity let's just assume f4 is ==. Then we have
>
> r0 = f5 (r1, r2 == r3)
>
> If f5 is PLUS then we get
>
> r0 = r1 + (r2 == r3)
>
> which is
>
> r0 = (r2 == r3) ? r1 + 1 : r1
>
> i.e. cmp r2, r3 \\ cinc r0, r1, eq. Since all comparisons return either zero
> (comparison failed) or 1 (comparison passed) a cinc should always work as
> long as the shiftable operator is PLUS.
> Operand 3 being an "arm_rhs_operand" shouldn't matter since it's just being
> compared to operand 2 and returning a 0 or 1.
Ah, thanks for explaining, it's been a while since I messed with these patterns...
Ok with the cmp fixed (as long as bootstrap and testing shows no problems)
>
> Thanks,
> Omar
^ permalink raw reply [flat|nested] 4+ messages in thread
end of thread, other threads:[~2020-08-07 7:52 UTC | newest]
Thread overview: 4+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2020-08-04 16:13 [PATCH 3/5][Arm] New pattern for CSINC instructions Omar Tahir
2020-08-06 11:40 ` Kyrylo Tkachov
2020-08-06 12:02 ` Omar Tahir
2020-08-07 7:52 ` Kyrylo Tkachov
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).