|
|
31df50 |
commit 6c175b3d170de2bb02b7bd45b3348eec05d28451
|
|
|
31df50 |
Author: Roger Sayle <roger@nextmovesoftware.com>
|
|
|
31df50 |
Date: Mon Jul 4 13:58:37 2022 +0100
|
|
|
31df50 |
|
|
|
31df50 |
PR target/105991: Recognize PLUS and XOR forms of rldimi in rs6000.md.
|
|
|
31df50 |
|
|
|
31df50 |
This patch addresses PR target/105991 where a change to prefer representing
|
|
|
31df50 |
shifts and adds at the tree-level as multiplications, causes problems for
|
|
|
31df50 |
the rldimi patterns in the powerpc backend. The issue is that rs6000.md
|
|
|
31df50 |
models this pattern using IOR, and some variants that have the equivalent
|
|
|
31df50 |
PLUS or XOR in the RTL fail to match some *rotl<mode>4_insert patterns.
|
|
|
31df50 |
This is fixed in this patch by adding a define_insn_and_split to locally
|
|
|
31df50 |
canonicalize the PLUS and XOR forms to the backend's preferred IOR form.
|
|
|
31df50 |
|
|
|
31df50 |
Backported from master.
|
|
|
31df50 |
|
|
|
31df50 |
2022-07-04 Roger Sayle <roger@nextmovesoftware.com>
|
|
|
31df50 |
Marek Polacek <polacek@redhat.com>
|
|
|
31df50 |
Segher Boessenkool <segher@kernel.crashing.org>
|
|
|
31df50 |
Kewen Lin <linkw@linux.ibm.com>
|
|
|
31df50 |
|
|
|
31df50 |
gcc/ChangeLog
|
|
|
31df50 |
PR target/105991
|
|
|
31df50 |
* config/rs6000/rs6000.md (rotl<mode>3_insert_3): Check that
|
|
|
31df50 |
exact_log2 doesn't return -1 (or zero).
|
|
|
31df50 |
(plus_xor): New code iterator.
|
|
|
31df50 |
(*rotl<mode>3_insert_3_): New define_insn_and_split.
|
|
|
31df50 |
|
|
|
31df50 |
gcc/testsuite/ChangeLog
|
|
|
31df50 |
PR target/105991
|
|
|
31df50 |
* gcc.target/powerpc/pr105991.c: New test case.
|
|
|
31df50 |
|
|
|
31df50 |
diff --git a/gcc/config/rs6000/rs6000.md b/gcc/config/rs6000/rs6000.md
|
|
|
31df50 |
index 64049a6e521..6082ded8c31 100644
|
|
|
31df50 |
--- a/gcc/config/rs6000/rs6000.md
|
|
|
31df50 |
+++ b/gcc/config/rs6000/rs6000.md
|
|
|
31df50 |
@@ -4178,7 +4178,8 @@ (define_insn "rotl<mode>3_insert_3"
|
|
|
31df50 |
(match_operand:GPR 4 "const_int_operand" "n"))
|
|
|
31df50 |
(ashift:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
|
|
|
31df50 |
(match_operand:SI 2 "const_int_operand" "n"))))]
|
|
|
31df50 |
- "INTVAL (operands[2]) == exact_log2 (UINTVAL (operands[4]) + 1)"
|
|
|
31df50 |
+ "INTVAL (operands[2]) > 0
|
|
|
31df50 |
+ && INTVAL (operands[2]) == exact_log2 (UINTVAL (operands[4]) + 1)"
|
|
|
31df50 |
{
|
|
|
31df50 |
if (<MODE>mode == SImode)
|
|
|
31df50 |
return "rlwimi %0,%1,%h2,0,31-%h2";
|
|
|
31df50 |
@@ -4187,6 +4188,24 @@ (define_insn "rotl<mode>3_insert_3"
|
|
|
31df50 |
}
|
|
|
31df50 |
[(set_attr "type" "insert")])
|
|
|
31df50 |
|
|
|
31df50 |
+; Canonicalize the PLUS and XOR forms to IOR for rotl<mode>3_insert_3
|
|
|
31df50 |
+(define_code_iterator plus_xor [plus xor])
|
|
|
31df50 |
+
|
|
|
31df50 |
+(define_insn_and_split "*rotl<mode>3_insert_3_"
|
|
|
31df50 |
+ [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
|
|
|
31df50 |
+ (plus_xor:GPR
|
|
|
31df50 |
+ (and:GPR (match_operand:GPR 3 "gpc_reg_operand" "0")
|
|
|
31df50 |
+ (match_operand:GPR 4 "const_int_operand" "n"))
|
|
|
31df50 |
+ (ashift:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
|
|
|
31df50 |
+ (match_operand:SI 2 "const_int_operand" "n"))))]
|
|
|
31df50 |
+ "INTVAL (operands[2]) > 0
|
|
|
31df50 |
+ && INTVAL (operands[2]) == exact_log2 (UINTVAL (operands[4]) + 1)"
|
|
|
31df50 |
+ "#"
|
|
|
31df50 |
+ "&& 1"
|
|
|
31df50 |
+ [(set (match_dup 0)
|
|
|
31df50 |
+ (ior:GPR (and:GPR (match_dup 3) (match_dup 4))
|
|
|
31df50 |
+ (ashift:GPR (match_dup 1) (match_dup 2))))])
|
|
|
31df50 |
+
|
|
|
31df50 |
(define_code_iterator plus_ior_xor [plus ior xor])
|
|
|
31df50 |
|
|
|
31df50 |
(define_split
|
|
|
31df50 |
diff --git a/gcc/testsuite/gcc.target/powerpc/pr105991.c b/gcc/testsuite/gcc.target/powerpc/pr105991.c
|
|
|
31df50 |
new file mode 100644
|
|
|
31df50 |
index 00000000000..0d9d130cb63
|
|
|
31df50 |
--- /dev/null
|
|
|
31df50 |
+++ b/gcc/testsuite/gcc.target/powerpc/pr105991.c
|
|
|
31df50 |
@@ -0,0 +1,12 @@
|
|
|
31df50 |
+/* { dg-do compile } */
|
|
|
31df50 |
+/* { dg-options "-O2" } */
|
|
|
31df50 |
+/* { dg-require-effective-target lp64 } */
|
|
|
31df50 |
+unsigned long long
|
|
|
31df50 |
+foo (unsigned long long value)
|
|
|
31df50 |
+{
|
|
|
31df50 |
+ value &= 0xffffffff;
|
|
|
31df50 |
+ value |= value << 32;
|
|
|
31df50 |
+ return value;
|
|
|
31df50 |
+}
|
|
|
31df50 |
+/* { dg-final { scan-assembler {\mrldimi\M} } } */
|
|
|
31df50 |
+
|