https://gcc.gnu.org/bugzilla/show_bug.cgi?id=106602

--- Comment #5 from Vineet Gupta <vineetg at rivosinc dot com> ---
Gimple for the test is

  _1 = a_2(D) << 6;
  _3 = _1 & 274877906880;   //  0x3f_ffff_ffc0

And 0x3f_ffff_ffc0 = 0x40_0000_0000 - 0x40

For !TARGET_ZBA there's a combiner pattern to match the seq of instruction
generated normally:  define_insn_and_split "zero_extendsidi2_shifted"

Trying 7, 8, 6 -> 9:
    7: r78:DI=0x4000000000
    8: r77:DI=r78:DI-0x40
      REG_DEAD r78:DI
      REG_EQUAL 0x3fffffffc0
    6: r76:DI=r79:DI<<0x6
      REG_DEAD r79:DI
    9: r75:DI=r76:DI&r77:DI
Successfully matched this instruction:
(set (reg:DI 75)
    (and:DI (ashift:DI (reg:DI 79)
            (const_int 6 [0x6]))
        (const_int 274877906880 [0x3fffffffc0])))


However for !bitmanip, RTL expansion splittable_const_int_operand() breaks up
0x40_0000_0000 into 1 << 38

(insn 7 6 8 2 (set (reg:DI 78)
  (const_int 1 [0x1])) 

(insn 8 7 9 2 (set (reg:DI 79)
  (ashift:DI (reg:DI 78)
    (const_int 38 [0x26]))) 

So we end up with 5 tot insn, which combine can't

And splittable_const_int_operand() has following check

  if (TARGET_64BIT && TARGET_ZBS && SINGLE_BIT_MASK_OPERAND (INTVAL (op)))
    return false;

which explains why 

1. zba alone doesn't generate slli.uw
2. zbs generates optimal slli+srli although these have nothing to do with zbs

Reply via email to