For a constant shift amount, add the following fold.
shl (zext (i1 X)), ShAmt --> select (X, 1 << ShAmt, 0)
https://rise4fun.com/Alive/IZ9
Fixes PR42257.
Differential D63382
[InstCombine] fold a shifted zext to a select spatel on Jun 15 2019, 4:47 PM. Authored by
Details
For a constant shift amount, add the following fold. https://rise4fun.com/Alive/IZ9 Fixes PR42257.
Diff Detail Event Timeline
Comment Actions IMO, this is the right canonicalization for IR because it's the smallest form. Also if the code was already in this form, it might have profile data on the select condition that would benefit codegen (for example, we might want to compare and branch on this instead of turning it into bit-logic). I've made several related changes to prefer 'select' in IR over bithacks. The only problem that I see is that the backend (DAGCombiner) isn't prepared to generically reverse this pattern yet (x86 might have some code that can be lifted): define i32 @shl_zext_bool(i1 %t) { %ext = zext i1 %t to i32 %shl = shl i32 %ext, 7 ret i32 %shl } define i32 @sel_zext_bool(i1 %t) { %shl= select i1 %t, i32 128, i32 0 ret i32 %shl } $ ./llc -o - selsh.ll -mtriple=aarch64-- shl_zext_bool: // @shl_zext_bool and w8, w0, #0x1 lsl w0, w8, #7 ret sel_zext_bool: // @sel_zext_bool tst w0, #0x1 mov w8, #128 csel w0, w8, wzr, ne ret
Comment Actions combineSelectOfTwoConstants seems to be the handler for X86 you mentioned . I like your idea to migrate it to a target-independent combine.
Comment Actions I haven't tested this on trunk, but I added the DAGCombiner reversals: There may still be regressions because most in-trunk targets don't enable the guarding hook. Example: Comment Actions @joanlluch - this is a case where we could transform incoming shift to select and benefit small targets as you've noted. Comment Actions Indeed, this seems to replace a shift that would be executed in all cases by a shift that will execute only if the incoming value was 1. Comment Actions @spatel I want to express my support to selects over bit manipulation instructions in IR, as stated above, in order to move such optimisations to DAGCombine. Ideally, this should involve the removal of some of the existing InstCombineSelect transformations, particularly most of the ones in foldSelectInstWithICmp. However, as I exposed earlier in LLVM-dev, the DAGCombine code should incorporate hooks to allow targets to decide whether such bihacks are actually profitable, or it's best to keep them as selects. Comment Actions Patch updated:
|
vectors of i1 too (isIntOrIntVectorTy(1))