345 lines · plain
1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --version 22; RUN: opt -passes=gvn -S < %s | FileCheck %s3 4 5define <4 x float> @ConvertVectors_ByRef(ptr %loc) {6; CHECK-LABEL: define <4 x float> @ConvertVectors_ByRef7; CHECK-SAME: (ptr [[LOC:%.*]]) {8; CHECK-NEXT: [[LOAD_VEC:%.*]] = load <4 x float>, ptr [[LOC]], align 169; CHECK-NEXT: [[SHUF:%.*]] = shufflevector <4 x float> [[LOAD_VEC]], <4 x float> poison, <4 x i32> <i32 0, i32 poison, i32 poison, i32 poison>10; CHECK-NEXT: [[GEP1:%.*]] = getelementptr inbounds [4 x float], ptr [[LOC]], i64 0, i64 111; CHECK-NEXT: [[TMP1:%.*]] = bitcast <4 x float> [[LOAD_VEC]] to i12812; CHECK-NEXT: [[TMP2:%.*]] = lshr i128 [[TMP1]], 3213; CHECK-NEXT: [[TMP3:%.*]] = trunc i128 [[TMP2]] to i3214; CHECK-NEXT: [[TMP4:%.*]] = bitcast i32 [[TMP3]] to float15; CHECK-NEXT: [[INS1:%.*]] = insertelement <4 x float> [[SHUF]], float [[TMP4]], i64 116; CHECK-NEXT: [[GEP2:%.*]] = getelementptr inbounds [4 x float], ptr [[LOC]], i64 0, i64 217; CHECK-NEXT: [[TMP5:%.*]] = lshr i128 [[TMP1]], 6418; CHECK-NEXT: [[TMP6:%.*]] = trunc i128 [[TMP5]] to i3219; CHECK-NEXT: [[TMP7:%.*]] = bitcast i32 [[TMP6]] to float20; CHECK-NEXT: [[INS2:%.*]] = insertelement <4 x float> [[INS1]], float [[TMP7]], i64 221; CHECK-NEXT: [[INS3:%.*]] = insertelement <4 x float> [[INS2]], float [[TMP7]], i64 322; CHECK-NEXT: ret <4 x float> [[INS3]]23;24 %load_vec = load <4 x float>, ptr %loc, align 1625 %shuf = shufflevector <4 x float> %load_vec, <4 x float> poison, <4 x i32> <i32 0, i32 poison, i32 poison, i32 poison>26 %gep1 = getelementptr inbounds [4 x float], ptr %loc, i64 0, i64 127 %load1 = load float, ptr %gep1, align 428 %ins1 = insertelement <4 x float> %shuf, float %load1, i64 129 %gep2 = getelementptr inbounds [4 x float], ptr %loc, i64 0, i64 230 %load2 = load float, ptr %gep2, align 831 %ins2 = insertelement <4 x float> %ins1, float %load2, i64 232 %ins3 = insertelement <4 x float> %ins2, float %load2, i64 333 ret <4 x float> %ins334}35 36define i64 @store_element_smaller_than_load(ptr %loc, <4 x i32> %v) {37; CHECK-LABEL: define i64 @store_element_smaller_than_load38; CHECK-SAME: (ptr [[LOC:%.*]], <4 x i32> [[V:%.*]]) {39; CHECK-NEXT: entry:40; CHECK-NEXT: store <4 x i32> [[V]], ptr [[LOC]], align 1641; CHECK-NEXT: [[GEP:%.*]] = getelementptr inbounds [4 x i32], ptr [[LOC]], i64 0, i64 242; CHECK-NEXT: [[TMP0:%.*]] = bitcast <4 x i32> [[V]] to i12843; CHECK-NEXT: [[TMP1:%.*]] = lshr i128 [[TMP0]], 6444; CHECK-NEXT: [[TMP2:%.*]] = trunc i128 [[TMP1]] to i6445; CHECK-NEXT: ret i64 [[TMP2]]46;47 entry:48 store <4 x i32> %v, ptr %loc49 %gep = getelementptr inbounds [4 x i32], ptr %loc, i64 0, i64 250 %ref = load i64, ptr %gep51 ret i64 %ref52}53 54define i64 @call_before_load(ptr %loc, <4 x i32> %v) {55; CHECK-LABEL: define i64 @call_before_load56; CHECK-SAME: (ptr [[LOC:%.*]], <4 x i32> [[V:%.*]]) {57; CHECK-NEXT: entry:58; CHECK-NEXT: store <4 x i32> [[V]], ptr [[LOC]], align 1659; CHECK-NEXT: call void @f(<4 x i32> [[V]])60; CHECK-NEXT: [[GEP:%.*]] = getelementptr inbounds [4 x i32], ptr [[LOC]], i64 0, i64 261; CHECK-NEXT: [[REF:%.*]] = load i64, ptr [[GEP]], align 462; CHECK-NEXT: ret i64 [[REF]]63;64 entry:65 store <4 x i32> %v, ptr %loc66 call void @f(<4 x i32> %v)67 %gep = getelementptr inbounds [4 x i32], ptr %loc, i64 0, i64 268 %ref = load i64, ptr %gep69 ret i64 %ref70}71 72define i64 @call_before_load_memory_none(ptr %loc, <4 x i32> %v) {73; CHECK-LABEL: define i64 @call_before_load_memory_none74; CHECK-SAME: (ptr [[LOC:%.*]], <4 x i32> [[V:%.*]]) {75; CHECK-NEXT: entry:76; CHECK-NEXT: store <4 x i32> [[V]], ptr [[LOC]], align 1677; CHECK-NEXT: call void @f_no_mem(<4 x i32> [[V]])78; CHECK-NEXT: [[GEP:%.*]] = getelementptr inbounds [4 x i32], ptr [[LOC]], i64 0, i64 279; CHECK-NEXT: [[TMP0:%.*]] = bitcast <4 x i32> [[V]] to i12880; CHECK-NEXT: [[TMP1:%.*]] = lshr i128 [[TMP0]], 6481; CHECK-NEXT: [[TMP2:%.*]] = trunc i128 [[TMP1]] to i6482; CHECK-NEXT: ret i64 [[TMP2]]83;84 entry:85 store <4 x i32> %v, ptr %loc86 call void @f_no_mem(<4 x i32> %v)87 %gep = getelementptr inbounds [4 x i32], ptr %loc, i64 0, i64 288 %ref = load i64, ptr %gep89 ret i64 %ref90}91 92define i64 @call_after_load(ptr %loc, <4 x i32> %v) {93; CHECK-LABEL: define i64 @call_after_load94; CHECK-SAME: (ptr [[LOC:%.*]], <4 x i32> [[V:%.*]]) {95; CHECK-NEXT: entry:96; CHECK-NEXT: store <4 x i32> [[V]], ptr [[LOC]], align 1697; CHECK-NEXT: [[GEP:%.*]] = getelementptr inbounds [4 x i32], ptr [[LOC]], i64 0, i64 298; CHECK-NEXT: [[TMP0:%.*]] = bitcast <4 x i32> [[V]] to i12899; CHECK-NEXT: [[TMP1:%.*]] = lshr i128 [[TMP0]], 64100; CHECK-NEXT: [[TMP2:%.*]] = trunc i128 [[TMP1]] to i64101; CHECK-NEXT: call void @f(<4 x i32> [[V]])102; CHECK-NEXT: ret i64 [[TMP2]]103;104 entry:105 store <4 x i32> %v, ptr %loc106 %gep = getelementptr inbounds [4 x i32], ptr %loc, i64 0, i64 2107 %ref = load i64, ptr %gep108 call void @f(<4 x i32> %v)109 ret i64 %ref110}111 112define double @store_element_smaller_than_load_float(ptr %loc, <4 x float> %v) {113; CHECK-LABEL: define double @store_element_smaller_than_load_float114; CHECK-SAME: (ptr [[LOC:%.*]], <4 x float> [[V:%.*]]) {115; CHECK-NEXT: store <4 x float> [[V]], ptr [[LOC]], align 16116; CHECK-NEXT: [[GEP:%.*]] = getelementptr inbounds [4 x float], ptr [[LOC]], i64 0, i64 2117; CHECK-NEXT: [[TMP1:%.*]] = bitcast <4 x float> [[V]] to i128118; CHECK-NEXT: [[TMP2:%.*]] = lshr i128 [[TMP1]], 64119; CHECK-NEXT: [[TMP3:%.*]] = trunc i128 [[TMP2]] to i64120; CHECK-NEXT: [[TMP4:%.*]] = bitcast i64 [[TMP3]] to double121; CHECK-NEXT: ret double [[TMP4]]122;123 store <4 x float> %v, ptr %loc124 %gep = getelementptr inbounds [4 x float], ptr %loc, i64 0, i64 2125 %ref = load double, ptr %gep126 ret double %ref127}128 129define i64 @load_as_scalar(ptr %loc, <2 x i32> %v) {130; CHECK-LABEL: define i64 @load_as_scalar131; CHECK-SAME: (ptr [[LOC:%.*]], <2 x i32> [[V:%.*]]) {132; CHECK-NEXT: store <2 x i32> [[V]], ptr [[LOC]], align 8133; CHECK-NEXT: [[TMP1:%.*]] = bitcast <2 x i32> [[V]] to i64134; CHECK-NEXT: ret i64 [[TMP1]]135;136 store <2 x i32> %v, ptr %loc137 %gep = getelementptr inbounds [4 x float], ptr %loc, i64 0138 %ref = load i64, ptr %gep139 ret i64 %ref140}141 142 143define i9 @load_as_scalar_larger(ptr %loc, <4 x i6> %v) {144; CHECK-LABEL: define i9 @load_as_scalar_larger145; CHECK-SAME: (ptr [[LOC:%.*]], <4 x i6> [[V:%.*]]) {146; CHECK-NEXT: store <4 x i6> [[V]], ptr [[LOC]], align 4147; CHECK-NEXT: [[TMP1:%.*]] = bitcast <4 x i6> [[V]] to i24148; CHECK-NEXT: [[TMP2:%.*]] = trunc i24 [[TMP1]] to i16149; CHECK-NEXT: [[TMP3:%.*]] = trunc i16 [[TMP2]] to i9150; CHECK-NEXT: ret i9 [[TMP3]]151;152 store <4 x i6> %v, ptr %loc153 %gep = getelementptr i9, ptr %loc, i64 0154 %ref = load i9, ptr %gep155 ret i9 %ref156}157 158 159define i4 @load_as_scalar_smaller(ptr %loc, <4 x i6> %v) {160; CHECK-LABEL: define i4 @load_as_scalar_smaller161; CHECK-SAME: (ptr [[LOC:%.*]], <4 x i6> [[V:%.*]]) {162; CHECK-NEXT: store <4 x i6> [[V]], ptr [[LOC]], align 4163; CHECK-NEXT: [[TMP1:%.*]] = bitcast <4 x i6> [[V]] to i24164; CHECK-NEXT: [[TMP2:%.*]] = trunc i24 [[TMP1]] to i8165; CHECK-NEXT: [[TMP3:%.*]] = trunc i8 [[TMP2]] to i4166; CHECK-NEXT: ret i4 [[TMP3]]167;168 store <4 x i6> %v, ptr %loc169 %gep = getelementptr i4, ptr %loc, i64 0170 %ref = load i4, ptr %gep171 ret i4 %ref172}173 174 175define i32 @load_vec_same_type(ptr %loc, <4 x i32> %v) {176; CHECK-LABEL: define i32 @load_vec_same_type177; CHECK-SAME: (ptr [[LOC:%.*]], <4 x i32> [[V:%.*]]) {178; CHECK-NEXT: entry:179; CHECK-NEXT: store <4 x i32> [[V]], ptr [[LOC]], align 16180; CHECK-NEXT: [[R:%.*]] = extractelement <4 x i32> [[V]], i32 1181; CHECK-NEXT: ret i32 [[R]]182;183 entry:184 store <4 x i32> %v, ptr %loc185 %gep = getelementptr inbounds [4 x i32], ptr %loc, i64 0186 %ref = load <4 x i32>, ptr %gep187 %r = extractelement <4 x i32> %ref, i32 1188 ret i32 %r189}190 191define i64 @load_vec_same_size_different_type1(ptr %loc, <4 x i32> %v) {192; CHECK-LABEL: define i64 @load_vec_same_size_different_type1193; CHECK-SAME: (ptr [[LOC:%.*]], <4 x i32> [[V:%.*]]) {194; CHECK-NEXT: entry:195; CHECK-NEXT: store <4 x i32> [[V]], ptr [[LOC]], align 16196; CHECK-NEXT: [[TMP0:%.*]] = bitcast <4 x i32> [[V]] to i128197; CHECK-NEXT: [[TMP1:%.*]] = bitcast i128 [[TMP0]] to <2 x i64>198; CHECK-NEXT: [[R:%.*]] = extractelement <2 x i64> [[TMP1]], i32 1199; CHECK-NEXT: ret i64 [[R]]200;201 entry:202 store <4 x i32> %v, ptr %loc203 %gep = getelementptr inbounds [4 x i32], ptr %loc, i64 0204 %ref = load <2 x i64>, ptr %gep205 %r = extractelement <2 x i64> %ref, i32 1206 ret i64 %r207}208 209define double @load_vec_same_size_different_type2(ptr %loc, <4 x i32> %v) {210; CHECK-LABEL: define double @load_vec_same_size_different_type2211; CHECK-SAME: (ptr [[LOC:%.*]], <4 x i32> [[V:%.*]]) {212; CHECK-NEXT: entry:213; CHECK-NEXT: store <4 x i32> [[V]], ptr [[LOC]], align 16214; CHECK-NEXT: [[TMP0:%.*]] = bitcast <4 x i32> [[V]] to i128215; CHECK-NEXT: [[TMP1:%.*]] = bitcast i128 [[TMP0]] to <2 x double>216; CHECK-NEXT: [[R:%.*]] = extractelement <2 x double> [[TMP1]], i32 1217; CHECK-NEXT: ret double [[R]]218;219 entry:220 store <4 x i32> %v, ptr %loc221 %gep = getelementptr inbounds [4 x i32], ptr %loc, i64 0222 %ref = load <2 x double>, ptr %gep223 %r = extractelement <2 x double> %ref, i32 1224 ret double %r225}226 227define i32 @load_subvector_same_type(ptr %loc, <4 x i32> %v) {228; CHECK-LABEL: define i32 @load_subvector_same_type229; CHECK-SAME: (ptr [[LOC:%.*]], <4 x i32> [[V:%.*]]) {230; CHECK-NEXT: entry:231; CHECK-NEXT: store <4 x i32> [[V]], ptr [[LOC]], align 16232; CHECK-NEXT: [[TMP0:%.*]] = bitcast <4 x i32> [[V]] to i128233; CHECK-NEXT: [[TMP1:%.*]] = trunc i128 [[TMP0]] to i64234; CHECK-NEXT: [[TMP2:%.*]] = bitcast i64 [[TMP1]] to <2 x i32>235; CHECK-NEXT: [[R:%.*]] = extractelement <2 x i32> [[TMP2]], i32 1236; CHECK-NEXT: ret i32 [[R]]237;238 entry:239 store <4 x i32> %v, ptr %loc240 %gep = getelementptr inbounds [4 x i32], ptr %loc, i64 0241 %ref = load <2 x i32>, ptr %gep242 %r = extractelement <2 x i32> %ref, i32 1243 ret i32 %r244}245 246define i64 @load_subvector_different_type(ptr %loc, <8 x i32> %v) {247; CHECK-LABEL: define i64 @load_subvector_different_type248; CHECK-SAME: (ptr [[LOC:%.*]], <8 x i32> [[V:%.*]]) {249; CHECK-NEXT: entry:250; CHECK-NEXT: store <8 x i32> [[V]], ptr [[LOC]], align 32251; CHECK-NEXT: [[TMP0:%.*]] = bitcast <8 x i32> [[V]] to i256252; CHECK-NEXT: [[TMP1:%.*]] = trunc i256 [[TMP0]] to i128253; CHECK-NEXT: [[TMP2:%.*]] = bitcast i128 [[TMP1]] to <2 x i64>254; CHECK-NEXT: [[R:%.*]] = extractelement <2 x i64> [[TMP2]], i32 1255; CHECK-NEXT: ret i64 [[R]]256;257 entry:258 store <8 x i32> %v, ptr %loc259 %gep = getelementptr inbounds [4 x i32], ptr %loc, i64 0260 %ref = load <2 x i64>, ptr %gep261 %r = extractelement <2 x i64> %ref, i32 1262 ret i64 %r263}264 265define i16 @load_subvector_different_type2(ptr %loc, <8 x i32> %v) {266; CHECK-LABEL: define i16 @load_subvector_different_type2267; CHECK-SAME: (ptr [[LOC:%.*]], <8 x i32> [[V:%.*]]) {268; CHECK-NEXT: entry:269; CHECK-NEXT: store <8 x i32> [[V]], ptr [[LOC]], align 32270; CHECK-NEXT: [[TMP0:%.*]] = bitcast <8 x i32> [[V]] to i256271; CHECK-NEXT: [[TMP1:%.*]] = trunc i256 [[TMP0]] to i32272; CHECK-NEXT: [[TMP2:%.*]] = bitcast i32 [[TMP1]] to <2 x i16>273; CHECK-NEXT: [[R:%.*]] = extractelement <2 x i16> [[TMP2]], i32 1274; CHECK-NEXT: ret i16 [[R]]275;276 entry:277 store <8 x i32> %v, ptr %loc278 %gep = getelementptr [2 x i16], ptr %loc, i64 0279 %ref = load <2 x i16>, ptr %gep280 %r = extractelement <2 x i16> %ref, i32 1281 ret i16 %r282}283 284define i4 @load_subvector_different_type3(ptr %loc, <8 x i8> %v) {285; CHECK-LABEL: define i4 @load_subvector_different_type3286; CHECK-SAME: (ptr [[LOC:%.*]], <8 x i8> [[V:%.*]]) {287; CHECK-NEXT: entry:288; CHECK-NEXT: store <8 x i8> [[V]], ptr [[LOC]], align 8289; CHECK-NEXT: [[TMP0:%.*]] = bitcast <8 x i8> [[V]] to i64290; CHECK-NEXT: [[TMP1:%.*]] = trunc i64 [[TMP0]] to i16291; CHECK-NEXT: [[TMP2:%.*]] = trunc i16 [[TMP1]] to i12292; CHECK-NEXT: [[TMP3:%.*]] = bitcast i12 [[TMP2]] to <3 x i4>293; CHECK-NEXT: [[R:%.*]] = extractelement <3 x i4> [[TMP3]], i32 1294; CHECK-NEXT: ret i4 [[R]]295;296 entry:297 store <8 x i8> %v, ptr %loc298 %gep = getelementptr [3 x i4], ptr %loc, i64 0299 %ref = load <3 x i4>, ptr %gep300 %r = extractelement <3 x i4> %ref, i32 1301 ret i4 %r302}303 304define i12 @load_subvector_different_type4(ptr %loc, <8 x i8> %v) {305; CHECK-LABEL: define i12 @load_subvector_different_type4306; CHECK-SAME: (ptr [[LOC:%.*]], <8 x i8> [[V:%.*]]) {307; CHECK-NEXT: entry:308; CHECK-NEXT: store <8 x i8> [[V]], ptr [[LOC]], align 8309; CHECK-NEXT: [[TMP0:%.*]] = bitcast <8 x i8> [[V]] to i64310; CHECK-NEXT: [[TMP1:%.*]] = trunc i64 [[TMP0]] to i24311; CHECK-NEXT: [[TMP2:%.*]] = bitcast i24 [[TMP1]] to <2 x i12>312; CHECK-NEXT: [[R:%.*]] = extractelement <2 x i12> [[TMP2]], i32 1313; CHECK-NEXT: ret i12 [[R]]314;315 entry:316 store <8 x i8> %v, ptr %loc317 %gep = getelementptr [2 x i12], ptr %loc, i64 0318 %ref = load <2 x i12>, ptr %gep319 %r = extractelement <2 x i12> %ref, i32 1320 ret i12 %r321}322 323define i6 @load_subvector_different_type5(ptr %loc, <8 x i8> %v) {324; CHECK-LABEL: define i6 @load_subvector_different_type5325; CHECK-SAME: (ptr [[LOC:%.*]], <8 x i8> [[V:%.*]]) {326; CHECK-NEXT: entry:327; CHECK-NEXT: store <8 x i8> [[V]], ptr [[LOC]], align 8328; CHECK-NEXT: [[TMP0:%.*]] = bitcast <8 x i8> [[V]] to i64329; CHECK-NEXT: [[TMP1:%.*]] = trunc i64 [[TMP0]] to i16330; CHECK-NEXT: [[TMP2:%.*]] = trunc i16 [[TMP1]] to i12331; CHECK-NEXT: [[TMP3:%.*]] = bitcast i12 [[TMP2]] to <2 x i6>332; CHECK-NEXT: [[R:%.*]] = extractelement <2 x i6> [[TMP3]], i32 1333; CHECK-NEXT: ret i6 [[R]]334;335 entry:336 store <8 x i8> %v, ptr %loc337 %gep = getelementptr [2 x i6], ptr %loc, i64 0338 %ref = load <2 x i6>, ptr %gep339 %r = extractelement <2 x i6> %ref, i32 1340 ret i6 %r341}342 343declare void @f(<4 x i32>)344declare void @f_no_mem(<4 x i32>) memory(none)345