; NOTE: Assertions have been autogenerated by utils/update_test_checks.py ; RUN: opt -passes=instcombine %s -S | FileCheck %s define ptr @vector_splat_indices_v2i64_ext0(ptr %a) { ; CHECK-LABEL: @vector_splat_indices_v2i64_ext0( ; CHECK-NEXT: [[RES:%.*]] = getelementptr i32, ptr [[A:%.*]], i64 4 ; CHECK-NEXT: ret ptr [[RES]] ; %gep = getelementptr i32, ptr %a, <2 x i64> %res = extractelement <2 x ptr> %gep, i32 0 ret ptr %res } define ptr @vector_splat_indices_nxv2i64_ext0(ptr %a) { ; CHECK-LABEL: @vector_splat_indices_nxv2i64_ext0( ; CHECK-NEXT: [[RES:%.*]] = getelementptr inbounds i32, ptr [[A:%.*]], i64 4 ; CHECK-NEXT: ret ptr [[RES]] ; %tmp = insertelement poison, i64 4, i32 0 %splatof4 = shufflevector %tmp, poison, zeroinitializer %gep = getelementptr inbounds i32, ptr %a, %splatof4 %res = extractelement %gep, i32 0 ret ptr %res } define ptr @vector_indices_v2i64_ext0(ptr %a, <2 x i64> %indices) { ; CHECK-LABEL: @vector_indices_v2i64_ext0( ; CHECK-NEXT: [[TMP1:%.*]] = extractelement <2 x i64> [[INDICES:%.*]], i64 0 ; CHECK-NEXT: [[RES:%.*]] = getelementptr i32, ptr [[A:%.*]], i64 [[TMP1]] ; CHECK-NEXT: ret ptr [[RES]] ; %gep = getelementptr i32, ptr %a, <2 x i64> %indices %res = extractelement <2 x ptr> %gep, i32 0 ret ptr %res } define ptr @vector_indices_nxv1i64_ext0(ptr %a, %indices) { ; CHECK-LABEL: @vector_indices_nxv1i64_ext0( ; CHECK-NEXT: [[TMP1:%.*]] = extractelement [[INDICES:%.*]], i64 0 ; CHECK-NEXT: [[RES:%.*]] = getelementptr i32, ptr [[A:%.*]], i64 [[TMP1]] ; CHECK-NEXT: ret ptr [[RES]] ; %gep = getelementptr i32, ptr %a, %indices %res = extractelement %gep, i32 0 ret ptr %res } define ptr @vector_splat_ptrs_v2i64_ext0(ptr %a, i64 %index) { ; CHECK-LABEL: @vector_splat_ptrs_v2i64_ext0( ; CHECK-NEXT: [[RES:%.*]] = getelementptr i32, ptr [[A:%.*]], i64 [[INDEX:%.*]] ; CHECK-NEXT: ret ptr [[RES]] ; %tmp = insertelement <2 x ptr> poison, ptr %a, i32 0 %splatofa = shufflevector <2 x ptr> %tmp, <2 x ptr> poison, <2 x i32> zeroinitializer %gep = getelementptr i32, <2 x ptr> %splatofa, i64 %index %res = extractelement <2 x ptr> %gep, i32 0 ret ptr %res } define ptr @vector_splat_ptrs_nxv2i64_ext0(ptr %a, i64 %index) { ; CHECK-LABEL: @vector_splat_ptrs_nxv2i64_ext0( ; CHECK-NEXT: [[RES:%.*]] = getelementptr i32, ptr [[A:%.*]], i64 [[INDEX:%.*]] ; CHECK-NEXT: ret ptr [[RES]] ; %tmp = insertelement poison, ptr %a, i32 0 %splatofa = shufflevector %tmp, poison, zeroinitializer %gep = getelementptr i32, %splatofa, i64 %index %res = extractelement %gep, i32 0 ret ptr %res } define ptr @vector_struct1_splat_indices_v4i64_ext1(ptr %a) { ; CHECK-LABEL: @vector_struct1_splat_indices_v4i64_ext1( ; CHECK-NEXT: [[RES:%.*]] = getelementptr { float, float }, ptr [[A:%.*]], i64 4, i32 0 ; CHECK-NEXT: ret ptr [[RES]] ; %gep = getelementptr {float, float}, ptr %a, <4 x i32> , i32 0 %res = extractelement <4 x ptr> %gep, i32 1 ret ptr %res } define ptr @vector_struct2_splat_indices_v4i64_ext1(ptr %a) { ; CHECK-LABEL: @vector_struct2_splat_indices_v4i64_ext1( ; CHECK-NEXT: [[RES:%.*]] = getelementptr { float, [8 x float] }, ptr [[A:%.*]], i64 2, i32 1, i64 4 ; CHECK-NEXT: ret ptr [[RES]] ; %gep = getelementptr {float, [8 x float]}, ptr %a, i32 2, i32 1, <4 x i32> %res = extractelement <4 x ptr> %gep, i32 1 ret ptr %res } ; Negative tests define ptr @vector_indices_nxv2i64_ext3(ptr %a, %indices) { ; CHECK-LABEL: @vector_indices_nxv2i64_ext3( ; CHECK-NEXT: [[GEP:%.*]] = getelementptr i32, ptr [[A:%.*]], [[INDICES:%.*]] ; CHECK-NEXT: [[RES:%.*]] = extractelement [[GEP]], i64 3 ; CHECK-NEXT: ret ptr [[RES]] ; %gep = getelementptr i32, ptr %a, %indices %res = extractelement %gep, i32 3 ret ptr %res } define ptr @vector_indices_nxv2i64_extN(ptr %a, %indices, i32 %N) { ; CHECK-LABEL: @vector_indices_nxv2i64_extN( ; CHECK-NEXT: [[GEP:%.*]] = getelementptr i32, ptr [[A:%.*]], [[INDICES:%.*]] ; CHECK-NEXT: [[RES:%.*]] = extractelement [[GEP]], i32 [[N:%.*]] ; CHECK-NEXT: ret ptr [[RES]] ; %gep = getelementptr i32, ptr %a, %indices %res = extractelement %gep, i32 %N ret ptr %res } define void @vector_indices_nxv2i64_mulitple_use(ptr %a, %indices, ptr %b, ptr %c) { ; CHECK-LABEL: @vector_indices_nxv2i64_mulitple_use( ; CHECK-NEXT: [[GEP:%.*]] = getelementptr i32, ptr [[A:%.*]], [[INDICES:%.*]] ; CHECK-NEXT: [[LANE0:%.*]] = extractelement [[GEP]], i64 0 ; CHECK-NEXT: [[LANE1:%.*]] = extractelement [[GEP]], i64 1 ; CHECK-NEXT: store ptr [[LANE0]], ptr [[B:%.*]], align 8 ; CHECK-NEXT: store ptr [[LANE1]], ptr [[C:%.*]], align 8 ; CHECK-NEXT: ret void ; %gep = getelementptr i32, ptr %a, %indices %lane0 = extractelement %gep, i32 0 %lane1 = extractelement %gep, i32 1 store ptr %lane0, ptr %b, align 8 store ptr %lane1, ptr %c, align 8 ret void } define ptr @vector_ptrs_and_indices_ext0( %a, %indices) { ; CHECK-LABEL: @vector_ptrs_and_indices_ext0( ; CHECK-NEXT: [[GEP:%.*]] = getelementptr i32, [[A:%.*]], [[INDICES:%.*]] ; CHECK-NEXT: [[RES:%.*]] = extractelement [[GEP]], i64 0 ; CHECK-NEXT: ret ptr [[RES]] ; %gep = getelementptr i32, %a, %indices %res = extractelement %gep, i32 0 ret ptr %res }