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