| ; 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 |
| } |