mirror of
https://github.com/RPCS3/llvm-mirror.git
synced 2024-11-26 04:32:44 +01:00
7714042905
This patch allows that scalable vector can fold extractelement and constant splat only when the lane index is lower than the minimum number of elements of the vector. Differential Revision: https://reviews.llvm.org/D103180
148 lines
6.2 KiB
LLVM
148 lines
6.2 KiB
LLVM
; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
|
|
; RUN: opt -instcombine %s -S | FileCheck %s
|
|
|
|
define i32* @vector_splat_indices_v2i64_ext0(i32* %a) {
|
|
; CHECK-LABEL: @vector_splat_indices_v2i64_ext0(
|
|
; CHECK-NEXT: [[RES:%.*]] = getelementptr i32, i32* [[A:%.*]], i64 4
|
|
; CHECK-NEXT: ret i32* [[RES]]
|
|
;
|
|
%gep = getelementptr i32, i32* %a, <2 x i64> <i64 4, i64 4>
|
|
%res = extractelement <2 x i32*> %gep, i32 0
|
|
ret i32* %res
|
|
}
|
|
|
|
define i32* @vector_splat_indices_nxv2i64_ext0(i32* %a) {
|
|
; CHECK-LABEL: @vector_splat_indices_nxv2i64_ext0(
|
|
; CHECK-NEXT: [[RES:%.*]] = getelementptr inbounds i32, i32* [[A:%.*]], i64 4
|
|
; CHECK-NEXT: ret i32* [[RES]]
|
|
;
|
|
%tmp = insertelement <vscale x 2 x i64> poison, i64 4, i32 0
|
|
%splatof4 = shufflevector <vscale x 2 x i64> %tmp, <vscale x 2 x i64> poison, <vscale x 2 x i32> zeroinitializer
|
|
%gep = getelementptr inbounds i32, i32* %a, <vscale x 2 x i64> %splatof4
|
|
%res = extractelement <vscale x 2 x i32*> %gep, i32 0
|
|
ret i32* %res
|
|
}
|
|
|
|
define i32* @vector_indices_v2i64_ext0(i32* %a, <2 x i64> %indices) {
|
|
; CHECK-LABEL: @vector_indices_v2i64_ext0(
|
|
; CHECK-NEXT: [[TMP0:%.*]] = extractelement <2 x i64> [[INDICES:%.*]], i32 0
|
|
; CHECK-NEXT: [[RES:%.*]] = getelementptr i32, i32* [[A:%.*]], i64 [[TMP0]]
|
|
; CHECK-NEXT: ret i32* [[RES]]
|
|
;
|
|
%gep = getelementptr i32, i32* %a, <2 x i64> %indices
|
|
%res = extractelement <2 x i32*> %gep, i32 0
|
|
ret i32* %res
|
|
}
|
|
|
|
define i32* @vector_indices_nxv1i64_ext0(i32* %a, <vscale x 1 x i64> %indices) {
|
|
; CHECK-LABEL: @vector_indices_nxv1i64_ext0(
|
|
; CHECK-NEXT: [[TMP0:%.*]] = extractelement <vscale x 1 x i64> [[INDICES:%.*]], i32 0
|
|
; CHECK-NEXT: [[RES:%.*]] = getelementptr i32, i32* [[A:%.*]], i64 [[TMP0]]
|
|
; CHECK-NEXT: ret i32* [[RES]]
|
|
;
|
|
%gep = getelementptr i32, i32* %a, <vscale x 1 x i64> %indices
|
|
%res = extractelement <vscale x 1 x i32*> %gep, i32 0
|
|
ret i32* %res
|
|
}
|
|
|
|
|
|
define i32* @vector_splat_ptrs_v2i64_ext0(i32* %a, i64 %index) {
|
|
; CHECK-LABEL: @vector_splat_ptrs_v2i64_ext0(
|
|
; CHECK-NEXT: [[RES:%.*]] = getelementptr i32, i32* [[A:%.*]], i64 [[INDEX:%.*]]
|
|
; CHECK-NEXT: ret i32* [[RES]]
|
|
;
|
|
%tmp = insertelement <2 x i32*> poison, i32* %a, i32 0
|
|
%splatofa = shufflevector <2 x i32*> %tmp, <2 x i32*> poison, <2 x i32> zeroinitializer
|
|
%gep = getelementptr i32, <2 x i32*> %splatofa, i64 %index
|
|
%res = extractelement <2 x i32*> %gep, i32 0
|
|
ret i32* %res
|
|
}
|
|
|
|
|
|
define i32* @vector_splat_ptrs_nxv2i64_ext0(i32* %a, i64 %index) {
|
|
; CHECK-LABEL: @vector_splat_ptrs_nxv2i64_ext0(
|
|
; CHECK-NEXT: [[RES:%.*]] = getelementptr i32, i32* [[A:%.*]], i64 [[INDEX:%.*]]
|
|
; CHECK-NEXT: ret i32* [[RES]]
|
|
;
|
|
%tmp = insertelement <vscale x 2 x i32*> poison, i32* %a, i32 0
|
|
%splatofa = shufflevector <vscale x 2 x i32*> %tmp, <vscale x 2 x i32*> poison, <vscale x 2 x i32> zeroinitializer
|
|
%gep = getelementptr i32, <vscale x 2 x i32*> %splatofa, i64 %index
|
|
%res = extractelement <vscale x 2 x i32*> %gep, i32 0
|
|
ret i32* %res
|
|
}
|
|
|
|
|
|
define float* @vector_struct1_splat_indices_v4i64_ext1({float, float}* %a) {
|
|
; CHECK-LABEL: @vector_struct1_splat_indices_v4i64_ext1(
|
|
; CHECK-NEXT: [[RES:%.*]] = getelementptr { float, float }, { float, float }* [[A:%.*]], i64 4, i32 0
|
|
; CHECK-NEXT: ret float* [[RES]]
|
|
;
|
|
%gep = getelementptr {float, float}, {float, float}* %a, <4 x i32> <i32 4, i32 4, i32 4, i32 4>, i32 0
|
|
%res = extractelement <4 x float*> %gep, i32 1
|
|
ret float* %res
|
|
}
|
|
|
|
|
|
define float* @vector_struct2_splat_indices_v4i64_ext1({float, [8 x float]}* %a) {
|
|
; CHECK-LABEL: @vector_struct2_splat_indices_v4i64_ext1(
|
|
; CHECK-NEXT: [[RES:%.*]] = getelementptr { float, [8 x float] }, { float, [8 x float] }* [[A:%.*]], i64 2, i32 1, i64 4
|
|
; CHECK-NEXT: ret float* [[RES]]
|
|
;
|
|
%gep = getelementptr {float, [8 x float]}, {float, [8 x float]}* %a, i32 2, i32 1, <4 x i32> <i32 4, i32 4, i32 4, i32 4>
|
|
%res = extractelement <4 x float*> %gep, i32 1
|
|
ret float* %res
|
|
}
|
|
|
|
|
|
; Negative tests
|
|
|
|
define i32* @vector_indices_nxv2i64_ext3(i32* %a, <vscale x 2 x i64> %indices) {
|
|
; CHECK-LABEL: @vector_indices_nxv2i64_ext3(
|
|
; CHECK-NEXT: [[GEP:%.*]] = getelementptr i32, i32* [[A:%.*]], <vscale x 2 x i64> [[INDICES:%.*]]
|
|
; CHECK-NEXT: [[RES:%.*]] = extractelement <vscale x 2 x i32*> [[GEP]], i32 3
|
|
; CHECK-NEXT: ret i32* [[RES]]
|
|
;
|
|
%gep = getelementptr i32, i32* %a, <vscale x 2 x i64> %indices
|
|
%res = extractelement <vscale x 2 x i32*> %gep, i32 3
|
|
ret i32* %res
|
|
}
|
|
|
|
define i32* @vector_indices_nxv2i64_extN(i32* %a, <vscale x 2 x i64> %indices, i32 %N) {
|
|
; CHECK-LABEL: @vector_indices_nxv2i64_extN(
|
|
; CHECK-NEXT: [[GEP:%.*]] = getelementptr i32, i32* [[A:%.*]], <vscale x 2 x i64> [[INDICES:%.*]]
|
|
; CHECK-NEXT: [[RES:%.*]] = extractelement <vscale x 2 x i32*> [[GEP]], i32 [[N:%.*]]
|
|
; CHECK-NEXT: ret i32* [[RES]]
|
|
;
|
|
%gep = getelementptr i32, i32* %a, <vscale x 2 x i64> %indices
|
|
%res = extractelement <vscale x 2 x i32*> %gep, i32 %N
|
|
ret i32* %res
|
|
}
|
|
|
|
define void @vector_indices_nxv2i64_mulitple_use(i32* %a, <vscale x 2 x i64> %indices, i32** %b, i32** %c) {
|
|
; CHECK-LABEL: @vector_indices_nxv2i64_mulitple_use(
|
|
; CHECK-NEXT: [[GEP:%.*]] = getelementptr i32, i32* [[A:%.*]], <vscale x 2 x i64> [[INDICES:%.*]]
|
|
; CHECK-NEXT: [[LANE0:%.*]] = extractelement <vscale x 2 x i32*> [[GEP]], i32 0
|
|
; CHECK-NEXT: [[LANE1:%.*]] = extractelement <vscale x 2 x i32*> [[GEP]], i32 1
|
|
; CHECK-NEXT: store i32* [[LANE0]], i32** [[B:%.*]], align 8
|
|
; CHECK-NEXT: store i32* [[LANE1]], i32** [[C:%.*]], align 8
|
|
; CHECK-NEXT: ret void
|
|
;
|
|
%gep = getelementptr i32, i32* %a, <vscale x 2 x i64> %indices
|
|
%lane0 = extractelement <vscale x 2 x i32*> %gep, i32 0
|
|
%lane1 = extractelement <vscale x 2 x i32*> %gep, i32 1
|
|
store i32* %lane0, i32** %b, align 8
|
|
store i32* %lane1, i32** %c, align 8
|
|
ret void
|
|
}
|
|
|
|
define i32* @vector_ptrs_and_indices_ext0(<vscale x 4 x i32*> %a, <vscale x 4 x i64> %indices) {
|
|
; CHECK-LABEL: @vector_ptrs_and_indices_ext0(
|
|
; CHECK-NEXT: [[GEP:%.*]] = getelementptr i32, <vscale x 4 x i32*> [[A:%.*]], <vscale x 4 x i64> [[INDICES:%.*]]
|
|
; CHECK-NEXT: [[RES:%.*]] = extractelement <vscale x 4 x i32*> [[GEP]], i32 0
|
|
; CHECK-NEXT: ret i32* [[RES]]
|
|
;
|
|
%gep = getelementptr i32, <vscale x 4 x i32*> %a, <vscale x 4 x i64> %indices
|
|
%res = extractelement <vscale x 4 x i32*> %gep, i32 0
|
|
ret i32* %res
|
|
}
|