I've done it again. ENOPATCH.
From: Roger Sayle <ro...@nextmovesoftware.com> Sent: 15 October 2023 09:13 To: 'gcc-patches@gcc.gnu.org' <gcc-patches@gcc.gnu.org> Cc: 'Claudiu Zissulescu' <claz...@gmail.com> Subject: [ARC PATCH] Split asl dst,1,src into bset dst,0,src to implement 1<<x. This patch adds a pre-reload splitter to arc.md, to use the bset (set specific bit instruction) to implement 1<<x (i.e. left shifts of one) on ARC processors that don't have a barrel shifter. Currently, int foo(int x) { return 1 << x; } when compiled with -O2 -mcpu=em is compiled as a loop: foo: mov_s r2,1 ;3 and.f lp_count,r0, 0x1f lpnz 2f add r2,r2,r2 nop 2: # end single insn loop j_s.d [blink] mov_s r0,r2 ;4 with this patch we instead generate a single instruction: foo: bset r0,0,r0 j_s [blink] Finger-crossed this passes Claudiu's nightly testing. This patch has been minimally tested by building a cross-compiler cc1 to arc-linux hosted on x86_64-pc-linux-gnu with no additional failures seen with make -k check. Ok for mainline? Thanks in advance. 2023-10-15 Roger Sayle <ro...@nextmovesoftware.com <mailto:ro...@nextmovesoftware.com> > gcc/ChangeLog * config/arc/arc.md (*ashlsi3_1): New pre-reload splitter to use bset dst,0,src to implement 1<<x on !TARGET_BARREL_SHIFTER. Cheers, Roger --
diff --git a/gcc/config/arc/arc.md b/gcc/config/arc/arc.md index a936a8b..22af0bf 100644 --- a/gcc/config/arc/arc.md +++ b/gcc/config/arc/arc.md @@ -3421,6 +3421,22 @@ archs4x, archs4xd" (set_attr "predicable" "no,no,yes,no,no") (set_attr "cond" "nocond,canuse,canuse,nocond,nocond")]) +;; Split asl dst,1,src into bset dst,0,src. +(define_insn_and_split "*ashlsi3_1" + [(set (match_operand:SI 0 "dest_reg_operand") + (ashift:SI (const_int 1) + (match_operand:SI 1 "nonmemory_operand")))] + "!TARGET_BARREL_SHIFTER + && arc_pre_reload_split ()" + "#" + "&& 1" + [(set (match_dup 0) + (ior:SI (ashift:SI (const_int 1) (match_dup 1)) + (const_int 0)))] + "" + [(set_attr "type" "shift") + (set_attr "length" "8")]) + (define_insn_and_split "*ashlsi3_nobs" [(set (match_operand:SI 0 "dest_reg_operand") (ashift:SI (match_operand:SI 1 "register_operand")