[PATCH] D26556: [InstCombine] don't widen most selects by hoisting an extend
Sanjay Patel via llvm-commits
llvm-commits at lists.llvm.org
Fri Nov 11 12:28:37 PST 2016
spatel created this revision.
spatel added reviewers: efriedma, mkuper, majnemer.
spatel added a subscriber: llvm-commits.
Herald added a subscriber: mcrosier.
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
}
https://reviews.llvm.org/D26556
Files:
lib/Transforms/InstCombine/InstructionCombining.cpp
test/Transforms/InstCombine/select-bitext.ll
Index: test/Transforms/InstCombine/select-bitext.ll
===================================================================
--- test/Transforms/InstCombine/select-bitext.ll
+++ test/Transforms/InstCombine/select-bitext.ll
@@ -5,8 +5,8 @@
define i64 @sel_sext(i32 %a, i1 %cmp) {
; CHECK-LABEL: @sel_sext(
-; CHECK-NEXT: [[TMP1:%.*]] = sext i32 %a to i64
-; CHECK-NEXT: [[EXT:%.*]] = select i1 %cmp, i64 [[TMP1]], i64 42
+; CHECK-NEXT: [[SEL:%.*]] = select i1 %cmp, i32 %a, i32 42
+; CHECK-NEXT: [[EXT:%.*]] = sext i32 [[SEL]] to i64
; CHECK-NEXT: ret i64 [[EXT]]
;
%sel = select i1 %cmp, i32 %a, i32 42
@@ -16,8 +16,8 @@
define <4 x i64> @sel_sext_vec(<4 x i32> %a, <4 x i1> %cmp) {
; CHECK-LABEL: @sel_sext_vec(
-; CHECK-NEXT: [[TMP1:%.*]] = sext <4 x i32> %a to <4 x i64>
-; CHECK-NEXT: [[EXT:%.*]] = select <4 x i1> %cmp, <4 x i64> [[TMP1]], <4 x i64> <i64 42, i64 42, i64 42, i64 42>
+; CHECK-NEXT: [[SEL:%.*]] = select <4 x i1> %cmp, <4 x i32> %a, <4 x i32> <i32 42, i32 42, i32 42, i32 42>
+; CHECK-NEXT: [[EXT:%.*]] = sext <4 x i32> [[SEL]] to <4 x i64>
; CHECK-NEXT: ret <4 x i64> [[EXT]]
;
%sel = select <4 x i1> %cmp, <4 x i32> %a, <4 x i32> <i32 42, i32 42, i32 42, i32 42>
@@ -27,8 +27,8 @@
define i64 @sel_zext(i32 %a, i1 %cmp) {
; CHECK-LABEL: @sel_zext(
-; CHECK-NEXT: [[TMP1:%.*]] = zext i32 %a to i64
-; CHECK-NEXT: [[EXT:%.*]] = select i1 %cmp, i64 [[TMP1]], i64 42
+; CHECK-NEXT: [[SEL:%.*]] = select i1 %cmp, i32 %a, i32 42
+; CHECK-NEXT: [[EXT:%.*]] = zext i32 [[SEL]] to i64
; CHECK-NEXT: ret i64 [[EXT]]
;
%sel = select i1 %cmp, i32 %a, i32 42
@@ -38,8 +38,8 @@
define <4 x i64> @sel_zext_vec(<4 x i32> %a, <4 x i1> %cmp) {
; CHECK-LABEL: @sel_zext_vec(
-; CHECK-NEXT: [[TMP1:%.*]] = zext <4 x i32> %a to <4 x i64>
-; CHECK-NEXT: [[EXT:%.*]] = select <4 x i1> %cmp, <4 x i64> [[TMP1]], <4 x i64> <i64 42, i64 42, i64 42, i64 42>
+; CHECK-NEXT: [[SEL:%.*]] = select <4 x i1> %cmp, <4 x i32> %a, <4 x i32> <i32 42, i32 42, i32 42, i32 42>
+; CHECK-NEXT: [[EXT:%.*]] = zext <4 x i32> [[SEL]] to <4 x i64>
; CHECK-NEXT: ret <4 x i64> [[EXT]]
;
%sel = select <4 x i1> %cmp, <4 x i32> %a, <4 x i32> <i32 42, i32 42, i32 42, i32 42>
Index: lib/Transforms/InstCombine/InstructionCombining.cpp
===================================================================
--- lib/Transforms/InstCombine/InstructionCombining.cpp
+++ lib/Transforms/InstCombine/InstructionCombining.cpp
@@ -780,8 +780,8 @@
/// Given an instruction with a select as one operand and a constant as the
/// other operand, try to fold the binary operator into the select arguments.
-/// This also works for Cast instructions, which obviously do not have a second
-/// operand.
+/// This also works for some Cast instructions, which obviously do not have a
+/// second operand.
Instruction *InstCombiner::FoldOpIntoSelect(Instruction &Op, SelectInst *SI) {
// Don't modify shared select instructions.
if (!SI->hasOneUse())
@@ -796,6 +796,20 @@
if (SI->getType()->getScalarType()->isIntegerTy(1))
return nullptr;
+ // If Op is an extend and this is not a select of constants, do not grow the
+ // select operand sizes by pulling the extend ahead of the select unless
+ // there's also a truncate before the select that will allow folding with the
+ // extend. This is particularly important for vectors because we want to use
+ // the narrowest operations possible for a given number of vector lanes.
+ auto isNonTruncVariable = [](Value *V) {
+ return !isa<Constant>(V) && !match(V, m_Trunc(m_Value()));
+ };
+
+ unsigned SrcWidth = SI->getType()->getScalarSizeInBits();
+ unsigned DstWidth = Op.getType()->getScalarSizeInBits();
+ if (SrcWidth < DstWidth && (isNonTruncVariable(TV) || isNonTruncVariable(FV)))
+ return nullptr;
+
// If it's a bitcast involving vectors, make sure it has the same number of
// elements on both sides.
if (auto *BC = dyn_cast<BitCastInst>(&Op)) {
-------------- next part --------------
A non-text attachment was scrubbed...
Name: D26556.77644.patch
Type: text/x-patch
Size: 3995 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20161111/bb0b99ce/attachment.bin>
More information about the llvm-commits
mailing list