This is related to the discussion in PR28160:
https://llvm.org/bugs/show_bug.cgi?id=28160
...but it's not the same example. It will help PR30773 more directly:
https://llvm.org/bugs/show_bug.cgi?id=30773
...because we handle selects with a constant operand on a different path than selects with two variables. Assuming this is the right thing to do, the next step will be to allow shrinking selects by sinking an extend after the select. That's easy because we already do that transform in InstCombiner::foldSelectExtConst(), but it's artificially limited to i1 types currently.
An example of the AVX2 codegen improvement from this patch using one of the vector regression tests:
Sext before:
define <4 x i64> @g1vec(<4 x i32> %a, <4 x i1> %cmp) { %ext = sext <4 x i32> %a to <4 x i64> %sel = select <4 x i1> %cmp, <4 x i64> %ext, <4 x i64> <i64 42, i64 42, i64 42, i64 42> ret <4 x i64> %ext } vpslld $31, %xmm1, %xmm1 vpmovsxdq %xmm1, %ymm1 vpmovsxdq %xmm0, %ymm0 vbroadcastsd LCPI1_0(%rip), %ymm2 vblendvpd %ymm1, %ymm0, %ymm2, %ymm0 retq
Sext after:
define <4 x i64> @g1vec(<4 x i32> %a, <4 x i1> %cmp) { %sel = select <4 x i1> %cmp, <4 x i32> %a, <4 x i32> <i32 42, i32 42, i32 42, i32 42> %ext = sext <4 x i32> %sel to <4 x i64> ret <4 x i64> %ext } vpslld $31, %xmm1, %xmm1 vbroadcastss LCPI1_0(%rip), %xmm2 <-- smaller load vblendvps %xmm1, %xmm0, %xmm2, %xmm0 <-- smaller select vpmovsxdq %xmm0, %ymm0 retq
The check for a leading trunc is to avoid regressing this test in test/Transforms/InstCombine/sext.ll:
define i32 @test8(i8 %a, i32 %f, i1 %p, i32* %z) { ; CHECK-LABEL: @test8( ; CHECK-NEXT: [[D:%.*]] = lshr i32 %f, 24 ; CHECK-NEXT: [[N:%.*]] = select i1 %p, i32 [[D]], i32 0 ; CHECK-NEXT: ret i32 [[N]] ; %d = lshr i32 %f, 24 %e = select i1 %p, i32 %d, i32 0 %s = trunc i32 %e to i16 %n = sext i16 %s to i32 ret i32 %n }
Do you want to match type sizes, though? Or at least make sure you're truncating more (or the same) as you're extending?
Like this:
vs just select + zext (using sext will make it even worse :-)