(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";
}
[(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
--- /dev/null
+/* { 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} } } */
+