Skip to content
Merged
Show file tree
Hide file tree
Changes from 7 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 7 additions & 0 deletions llvm/lib/Transforms/InstCombine/InstCombineVectorOps.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -542,6 +542,13 @@ Instruction *InstCombinerImpl::visitExtractElementInst(ExtractElementInst &EI) {
}
}
} else if (auto *SVI = dyn_cast<ShuffleVectorInst>(I)) {
// extractelt (shufflevector %v1, %v2, splat-mask) idx ->
// extractelt %v1, splat-mask[0]
auto mask = SVI->getShuffleMask();
if (mask[0] != PoisonMaskElem && all_equal(mask))
return ExtractElementInst::Create(SVI->getOperand(0),
Builder.getInt64(mask[0]));

// If this is extracting an element from a shufflevector, figure out where
// it came from and extract from the appropriate input element instead.
// Restrict the following transformation to fixed-length vector.
Expand Down
54 changes: 54 additions & 0 deletions llvm/test/Transforms/InstCombine/vec_extract_through_broadcast.ll
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
; RUN: opt -passes=instcombine -S < %s | FileCheck %s

define float @extract_from_zero_init_shuffle(<2 x float> %1, i64 %idx) {
; CHECK-LABEL: @extract_from_zero_init_shuffle(
; CHECK-NEXT: [[TMP1:%.*]] = extractelement <2 x float> [[W:%.*]], i64 0
; CHECK-NEXT: ret float [[TMP1]]
;
%3 = shufflevector <2 x float> %1, <2 x float> poison, <4 x i32> zeroinitializer
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

(style) avoid using numbers for variable names (%vec, %shuffle and %extract would be better)

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done in latest push, please take a look. Thanks.

%4 = extractelement <4 x float> %3, i64 %idx
ret float %4
}


define float @extract_from_general_splat(<2 x float> %1, i64 %idx) {
; CHECK-LABEL: @extract_from_general_splat(
; CHECK-NEXT: [[TMP1:%.*]] = extractelement <2 x float> [[W:%.*]], i64 1
; CHECK-NEXT: ret float [[TMP1]]
;
%3 = shufflevector <2 x float> %1, <2 x float> poison, <4 x i32> <i32 1, i32 1, i32 1, i32 1>
%4 = extractelement <4 x float> %3, i64 %idx
ret float %4
}

define float @extract_from_general_scalable_splat(<vscale x 2 x float> %1, i64 %idx) {
; CHECK-LABEL: @extract_from_general_scalable_splat(
; CHECK-NEXT: [[TMP1:%.*]] = extractelement <vscale x 2 x float> [[W:%.*]], i64 0
; CHECK-NEXT: ret float [[TMP1]]
;
%3 = shufflevector <vscale x 2 x float> %1, <vscale x 2 x float> poison, <vscale x 4 x i32> zeroinitializer
%4 = extractelement <vscale x 4 x float> %3, i64 %idx
ret float %4
}

define float @no_extract_from_general_no_splat_0(<2 x float> %1, i64 %idx) {
; CHECK-LABEL: @no_extract_from_general_no_splat_0(
; CHECK-NEXT: [[TMP1:%.*]] = shufflevector <2 x float> [[W:%.*]], <2 x float> poison, <4 x i32> <i32 poison, i32 1, i32 1, i32 1>
; CHECK-NEXT: [[TMP2:%.*]] = extractelement <4 x float> [[TMP1]], i64 %idx
; CHECK-NEXT: ret float [[TMP2]]
;
%3 = shufflevector <2 x float> %1, <2 x float> poison, <4 x i32> <i32 poison, i32 1, i32 1, i32 1>
%4 = extractelement <4 x float> %3, i64 %idx
ret float %4
}

define float @no_extract_from_general_no_splat_1(<2 x float> %1, i64 %idx) {
; CHECK-LABEL: @no_extract_from_general_no_splat_1(
; CHECK-NEXT: [[TMP1:%.*]] = shufflevector <2 x float> [[W:%.*]], <2 x float> poison, <4 x i32> <i32 1, i32 poison, i32 1, i32 1>
; CHECK-NEXT: [[TMP2:%.*]] = extractelement <4 x float> [[TMP1]], i64 %idx
; CHECK-NEXT: ret float [[TMP2]]
;
%3 = shufflevector <2 x float> %1, <2 x float> poison, <4 x i32> <i32 1, i32 poison, i32 1, i32 1>
%4 = extractelement <4 x float> %3, i64 %idx
ret float %4
}