1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py 2; RUN: opt -S -instcombine < %s | FileCheck %s 3 4; This test is used to verify we are not crashing at Assertion `CastInst::castIsValid(opc, C, Ty) && "Invalid constantexpr cast!". 5define <vscale x 2 x i8*> @gep_index_type_is_scalable(i8* %p) { 6; CHECK-LABEL: @gep_index_type_is_scalable( 7; CHECK-NEXT: [[GEP:%.*]] = getelementptr i8, i8* [[P:%.*]], <vscale x 2 x i64> undef 8; CHECK-NEXT: ret <vscale x 2 x i8*> [[GEP]] 9; 10 %gep = getelementptr i8, i8* %p, <vscale x 2 x i64> undef 11 ret <vscale x 2 x i8*> %gep 12} 13 14; This test serves to verify code changes for "GEP.getNumIndices() == 1". 15define <vscale x 4 x i32>* @gep_num_of_indices_1(<vscale x 4 x i32>* %p) { 16; CHECK-LABEL: @gep_num_of_indices_1( 17; CHECK-NEXT: [[GEP:%.*]] = getelementptr <vscale x 4 x i32>, <vscale x 4 x i32>* [[P:%.*]], i64 1 18; CHECK-NEXT: ret <vscale x 4 x i32>* [[GEP]] 19; 20 %gep = getelementptr <vscale x 4 x i32>, <vscale x 4 x i32>* %p, i64 1 21 ret <vscale x 4 x i32>* %gep 22} 23 24; This test serves to verify code changes for "GEP.getNumOperands() == 2". 25define void @gep_bitcast(i8* %p) { 26; CHECK-LABEL: @gep_bitcast( 27; CHECK-NEXT: [[CAST:%.*]] = bitcast i8* [[P:%.*]] to <vscale x 16 x i8>* 28; CHECK-NEXT: store <vscale x 16 x i8> zeroinitializer, <vscale x 16 x i8>* [[CAST]], align 16 29; CHECK-NEXT: [[GEP2:%.*]] = getelementptr <vscale x 16 x i8>, <vscale x 16 x i8>* [[CAST]], i64 1 30; CHECK-NEXT: store <vscale x 16 x i8> zeroinitializer, <vscale x 16 x i8>* [[GEP2]], align 16 31; CHECK-NEXT: ret void 32; 33 %cast = bitcast i8* %p to <vscale x 16 x i8>* 34 %gep1 = getelementptr <vscale x 16 x i8>, <vscale x 16 x i8>* %cast, i64 0 35 store <vscale x 16 x i8> zeroinitializer, <vscale x 16 x i8>* %gep1 36 %gep2 = getelementptr <vscale x 16 x i8>, <vscale x 16 x i8>* %cast, i64 1 37 store <vscale x 16 x i8> zeroinitializer, <vscale x 16 x i8>* %gep2 38 ret void 39} 40 41; These tests serve to verify code changes when underlying gep ptr is alloca. 42; This test is to verify 'inbounds' is added when it's valid to accumulate constant offset. 43define i32 @gep_alloca_inbounds_vscale_zero() { 44; CHECK-LABEL: @gep_alloca_inbounds_vscale_zero( 45; CHECK-NEXT: [[A:%.*]] = alloca <vscale x 4 x i32>, align 16 46; CHECK-NEXT: [[TMP:%.*]] = getelementptr inbounds <vscale x 4 x i32>, <vscale x 4 x i32>* [[A]], i64 0, i64 2 47; CHECK-NEXT: [[LOAD:%.*]] = load i32, i32* [[TMP]], align 8 48; CHECK-NEXT: ret i32 [[LOAD]] 49; 50 %a = alloca <vscale x 4 x i32> 51 %tmp = getelementptr <vscale x 4 x i32>, <vscale x 4 x i32>* %a, i32 0, i32 2 52 %load = load i32, i32* %tmp 53 ret i32 %load 54} 55 56; This test is to verify 'inbounds' is not added when a constant offset can not be determined at compile-time. 57define i32 @gep_alloca_inbounds_vscale_nonzero() { 58; CHECK-LABEL: @gep_alloca_inbounds_vscale_nonzero( 59; CHECK-NEXT: [[A:%.*]] = alloca <vscale x 4 x i32>, align 16 60; CHECK-NEXT: [[TMP:%.*]] = getelementptr <vscale x 4 x i32>, <vscale x 4 x i32>* [[A]], i64 1, i64 2 61; CHECK-NEXT: [[LOAD:%.*]] = load i32, i32* [[TMP]], align 8 62; CHECK-NEXT: ret i32 [[LOAD]] 63; 64 %a = alloca <vscale x 4 x i32> 65 %tmp = getelementptr <vscale x 4 x i32>, <vscale x 4 x i32>* %a, i32 1, i32 2 66 %load = load i32, i32* %tmp 67 ret i32 %load 68} 69