<table border="1" cellspacing="0" cellpadding="8">
    <tr>
        <th>Issue</th>
        <td>
            <a href=https://github.com/llvm/llvm-project/issues/122425>122425</a>
        </td>
    </tr>

    <tr>
        <th>Summary</th>
        <td>
            Integer halves shuffle pattern produces worse codegen with canonical IR
        </td>
    </tr>

    <tr>
      <th>Labels</th>
      <td>
            backend:AMDGPU,
            backend:X86,
            llvm:SelectionDAG
      </td>
    </tr>

    <tr>
      <th>Assignees</th>
      <td>
      </td>
    </tr>

    <tr>
      <th>Reporter</th>
      <td>
          arsenm
      </td>
    </tr>
</table>

<pre>
    While investigating a regressions related to lowered shufflevector as an integer, I noticed this code does a worse job with canonical IR.

For old AMDGPU targets without v_perm_b32, the there is an extra instruction. With perm it's a neutral net result (though I still prefer the non-canonical output, since it involves fewer steps in codegen since it doesn't rely on the SDWA pass to clean up an extra instruction).

X86 also has one additional instruction in the canonical case

```
; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py UTC_ARGS: --version 5
; RUN: llc -mtriple=amdgcn-amd-amdhsa -mcpu=gfx700 < %s | FileCheck -check-prefix=GFX7 %s
; RUN: llc -mtriple=amdgcn-amd-amdhsa -mcpu=gfx803 < %s | FileCheck -check-prefix=GFX8 %s
; RUN: llc -mtriple=amdgcn-amd-amdhsa -mcpu=gfx900 < %s | FileCheck -check-prefix=GFX9 %s
; RUN: llc -mtriple=x86_64 -mattr=+avx2< %s | FileCheck -check-prefix=X86

define i32 @shuffle_as_int(i32 %arg) {
; GFX7-LABEL: shuffle_as_int:
; GFX7:       ; %bb.0:
; GFX7-NEXT:    s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
; GFX7-NEXT: v_lshrrev_b32_e32 v1, 16, v0
; GFX7-NEXT:    v_alignbit_b32 v0, v1, v0, 16
; GFX7-NEXT:    s_setpc_b64 s[30:31]
;
; GFX8-LABEL: shuffle_as_int:
; GFX8:       ; %bb.0:
; GFX8-NEXT:    s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
; GFX8-NEXT:    s_mov_b32 s4, 0x7060706
; GFX8-NEXT: v_perm_b32 v0, v0, v0, s4
; GFX8-NEXT:    s_setpc_b64 s[30:31]
;
; GFX9-LABEL: shuffle_as_int:
; GFX9:       ; %bb.0:
; GFX9-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
; GFX9-NEXT:    s_mov_b32 s4, 0x7060706
; GFX9-NEXT:    v_perm_b32 v0, v0, v0, s4
; GFX9-NEXT: s_setpc_b64 s[30:31]
;
; X86-LABEL: shuffle_as_int:
; X86:       # %bb.0:
; X86-NEXT:    movl %edi, %eax
; X86-NEXT:    shrl $16, %eax
; X86-NEXT:    shldl $16, %edi, %eax
; X86-NEXT:    retq
  %arg.lshr16 = lshr i32 %arg, 16
  %arg.hi16.in.lo = and i32 %arg.lshr16, 65535
  %zero.low16 = shl i32 %arg.lshr16, 16
  %or = or i32 %arg.hi16.in.lo, %zero.low16
  ret i32 %or
}

; Same function run through instcombine, codegen is worse.
define i32 @shuffle_as_int_canonical(i32 %arg) {
; GFX7-LABEL: shuffle_as_int_canonical:
; GFX7:       ; %bb.0:
; GFX7-NEXT:    s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
; GFX7-NEXT:    v_lshrrev_b32_e32 v1, 16, v0
; GFX7-NEXT:    v_and_b32_e32 v0, 0xffff0000, v0
; GFX7-NEXT: v_or_b32_e32 v0, v1, v0
; GFX7-NEXT:    s_setpc_b64 s[30:31]
;
; GFX8-LABEL: shuffle_as_int_canonical:
; GFX8:       ; %bb.0:
; GFX8-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
; GFX8-NEXT:    v_and_b32_e32 v1, 0xffff0000, v0
; GFX8-NEXT:    v_or_b32_sdwa v0, v0, v1 dst_sel:DWORD dst_unused:UNUSED_PAD src0_sel:WORD_1 src1_sel:DWORD
; GFX8-NEXT: s_setpc_b64 s[30:31]
;
; GFX9-LABEL: shuffle_as_int_canonical:
; GFX9: ; %bb.0:
; GFX9-NEXT:    s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
; GFX9-NEXT:    v_lshrrev_b32_e32 v1, 16, v0
; GFX9-NEXT:    s_mov_b32 s4, 0xffff0000
; GFX9-NEXT:    v_and_or_b32 v0, v0, s4, v1
; GFX9-NEXT: s_setpc_b64 s[30:31]
;
; X86-LABEL: shuffle_as_int_canonical:
; X86: # %bb.0:
; X86-NEXT:    movl %edi, %eax
; X86-NEXT:    shrl $16, %eax
; X86-NEXT:    andl $-65536, %edi # imm = 0xFFFF0000
; X86-NEXT:    orl %edi, %eax
; X86-NEXT:    retq
  %arg.lshr16 = lshr i32 %arg, 16
  %zero.low16 = and i32 %arg, -65536
  %or = or disjoint i32 %arg.lshr16, %zero.low16
  ret i32 %or
}
```
</pre>
<img width="1" height="1" alt="" src="http://email.email.llvm.org/o/eJzMWFFz2joW_jXi5QyMLGODH3ggcel05m7vnaaZ5s0j2wdbrSx5Jdmh--t3ZJxAKLnQ9HZ2O4WA9Z3zHX2SzmfMrRWVQlyR6IZE6YR3rtZmxY1F1UxyXX5ffamFRBCqR-tExZ1QFXAwWBm0VmhlwaDkDktwGqR-RIMl2LrbbiX2WDhtgFvgCoRyWKEh7BY-gNJOFD6mFhYKXSKUGi1weNTGInzVOTwKV0PBlVai4BI-fJoRuiZ0vdEGtCxh_a_0_V_34Lip0NkBrjsHfdaiabI8ZJ7J1ehfBkEMReDOGQ5CWWe6wgmtZvDF8_gYEI6whS9CYecMl6DQgUHbSQeELX3-qoYPYJ2QElqDWzQDg9JqeqhUd67tnGe3QhUIwnn5tOzRwhYf0YB12FoQaph5heoA9CoowhaeV34HrYb8d-mXNbTcWq9xIZEr6Nqz0yEsGWV6WMbApdVQcwtaIfCyFB7C5XGAr8JTHMovuMV9ChLT8T9dk_AGPv75-R0J17C2Fo0b1r7mPUKOqIB3Tleo0Ax7If8OnRPSErbp2pI7zKQsMofWZUWNxTc7a7_D_efbbP3p_Z3POZ32aPx-gmhk-3T_0Q9IWcC0cUa0EkmY8qasCjXlTelfteUwbYq2I2FabXcLSoGEt0BYZIEsbmEjJN56PpgOtFO_aGJHwvT95mEx4N7OtqThT7Atf5Et-am5JZfZdss4i-cwbbhzhoQpYTe837ErOR6W8X6TlLgVCkGEDMicjgc_4zYTyhG2HK6ziJuKsATI4masyes__WN98-4PX9pJWLg-Qvnx_T9_hbAoz2f0JWT68d3D5xFns0cuXKEc9E0xlEA9M-7ao2-y-nY0eC5Tn0lbG4O97yQZhgz6wB_pIPbvPX2Fvc-4FJXKhfNxHufRwRizj3-tbouuLbI8noMl0U3o5xgGJEr3AYew5VW6LS_rtvzHdDvJ1OhBNrBzP2W6W9CYLmh8Dn9o109iHb3b-asU14qVXCVWclms5Jn_l5RKflKp5OXuulKs42KvUuphGV8Wyp_5g04s_FEnn-ao3kb30oOwFL5C_4nvzkNtbTx0vj9ff4-U5Qn0cnqD7t-ErmHsRTN_uIMYSJiC_wjHbWo8pM_YWgTxTKiZ1AOeq_IIPmbyUXEUhdFT4H_Q6JnUjyOJreX5oAOVNgNSHxdzxD3O8JB3iDPonuDa-Kkv0tG7wxu44w3CtlN7ozedd3oz3MP4G4BCN7lQ6PM-3YYIu7__ml3o69nz3cIbO_xRgv-DXj-crLe2e1UeQuj-EG-32y2llL4e2mfanIQ9m8Rvs4dXRP8po_jnXOJEuuDvpTsJHdWz5SN_2QkDKK3LLPoppl_-_JQO3zvVWSxJuL7_eH_3Ls3-WqdgTUFHoMdlgb8SHIeen_8vG88ryzBY0GXz-dVdn7xt11-wredle43Hr_V-0U49a7_1f4tznVN69LD_mXtxtTevqXeLIwMbKhJNM3gA3W02m82RoCdJtLm2sLf63ol9vfQ8Dx3r_8G7SmG_aqHcebe72sCefnlOylVYJmHCJ7gKFmE8T2gQJ5N6lS9wnpcci3KZhCwKi20cL4PFNqJFGeSYTMSKURbRIKA0ZmyezIIyn_MQebJd5tuwpGROseFCzqTsm5k21URY2-EqYGzOoonkOUo7PBhhLOfFN1S-g-yfOhDGCLt9MeA31tNVn5GE6zuUOHhvun7vx6J0YlZ-bJp3lSVzKoV19sDvhJO4-rB_TgI1H54YjFsaWu4cGgWt0WVX4OjUz9b9w9OSSWfkqnautX6Dsw1hm0q4ustnhW4I2ww17v9MW6O_YuEI2wwS-F_towr9iv03AAD__xUXN_A">