356 lines · plain
1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py2; RUN: opt < %s -passes=instcombine -S | FileCheck %s3 4target datalayout = "n32"5 6@var_7 = external global i8, align 17@var_1 = external global i32, align 48@var_0 = external global i16, align 29@var_5 = external global i64, align 810@arr_2 = external global [0 x i32], align 411@arr_4 = external global [0 x i16], align 212@arr_3 = external global [8 x i32], align 1613 14define void @_Z4testv() {15; CHECK-LABEL: @_Z4testv(16; CHECK-NEXT: bb:17; CHECK-NEXT: [[I:%.*]] = load i8, ptr @var_7, align 118; CHECK-NEXT: [[I1:%.*]] = icmp eq i8 [[I]], -119; CHECK-NEXT: [[I4:%.*]] = load i16, ptr @var_0, align 220; CHECK-NEXT: br i1 [[I1]], label [[BB10:%.*]], label [[BB9:%.*]]21; CHECK: bb9:22; CHECK-NEXT: br label [[BB12:%.*]]23; CHECK: bb10:24; CHECK-NEXT: [[I2:%.*]] = load i32, ptr @var_1, align 425; CHECK-NEXT: [[I3:%.*]] = icmp eq i32 [[I2]], 026; CHECK-NEXT: [[I6:%.*]] = load i64, ptr @var_5, align 827; CHECK-NEXT: [[I5:%.*]] = sext i16 [[I4]] to i6428; CHECK-NEXT: [[I7:%.*]] = select i1 [[I3]], i64 [[I6]], i64 [[I5]]29; CHECK-NEXT: [[I11:%.*]] = trunc i64 [[I7]] to i3230; CHECK-NEXT: br label [[BB12]]31; CHECK: bb12:32; CHECK-NEXT: [[STOREMERGE:%.*]] = phi i32 [ 1, [[BB9]] ], [ [[I11]], [[BB10]] ]33; CHECK-NEXT: store i32 [[STOREMERGE]], ptr @arr_2, align 434; CHECK-NEXT: store i16 [[I4]], ptr @arr_4, align 235; CHECK-NEXT: [[I8:%.*]] = sext i16 [[I4]] to i3236; CHECK-NEXT: store i32 [[I8]], ptr @arr_3, align 437; CHECK-NEXT: store i32 [[STOREMERGE]], ptr getelementptr inbounds nuw (i8, ptr @arr_2, i64 4), align 438; CHECK-NEXT: store i16 [[I4]], ptr getelementptr inbounds nuw (i8, ptr @arr_4, i64 2), align 239; CHECK-NEXT: store i32 [[I8]], ptr getelementptr inbounds nuw (i8, ptr @arr_3, i64 4), align 440; CHECK-NEXT: ret void41;42bb:43 %i = load i8, ptr @var_7, align 144 %i1 = icmp eq i8 %i, -145 %i2 = load i32, ptr @var_1, align 446 %i3 = icmp eq i32 %i2, 047 %i4 = load i16, ptr @var_0, align 248 %i5 = sext i16 %i4 to i6449 %i6 = load i64, ptr @var_5, align 850 %i7 = select i1 %i3, i64 %i6, i64 %i551 %i8 = sext i16 %i4 to i3252 br i1 %i1, label %bb10, label %bb953 54bb9: ; preds = %bb55 store i32 1, ptr @arr_2, align 456 store i16 %i4, ptr @arr_4, align 257 store i32 %i8, ptr @arr_3, align 458 store i32 1, ptr getelementptr inbounds ([0 x i32], ptr @arr_2, i64 0, i64 1), align 459 store i16 %i4, ptr getelementptr inbounds ([0 x i16], ptr @arr_4, i64 0, i64 1), align 260 store i32 %i8, ptr getelementptr inbounds ([8 x i32], ptr @arr_3, i64 0, i64 1), align 461 br label %bb1262 63bb10: ; preds = %bb64 %i11 = trunc i64 %i7 to i3265 store i32 %i11, ptr @arr_2, align 466 store i16 %i4, ptr @arr_4, align 267 store i32 %i8, ptr @arr_3, align 468 store i32 %i11, ptr getelementptr inbounds ([0 x i32], ptr @arr_2, i64 0, i64 1), align 469 store i16 %i4, ptr getelementptr inbounds ([0 x i16], ptr @arr_4, i64 0, i64 1), align 270 store i32 %i8, ptr getelementptr inbounds ([8 x i32], ptr @arr_3, i64 0, i64 1), align 471 br label %bb1272 73bb12: ; preds = %bb10, %bb974 ret void75}76 77define half @diff_types_same_width_merge(i1 %cond, half %a, i16 %b) {78; CHECK-LABEL: @diff_types_same_width_merge(79; CHECK-NEXT: entry:80; CHECK-NEXT: br i1 [[COND:%.*]], label [[BB0:%.*]], label [[BB1:%.*]]81; CHECK: BB0:82; CHECK-NEXT: br label [[SINK:%.*]]83; CHECK: BB1:84; CHECK-NEXT: [[TMP0:%.*]] = bitcast i16 [[B:%.*]] to half85; CHECK-NEXT: br label [[SINK]]86; CHECK: sink:87; CHECK-NEXT: [[STOREMERGE:%.*]] = phi half [ [[TMP0]], [[BB1]] ], [ [[A:%.*]], [[BB0]] ]88; CHECK-NEXT: ret half [[STOREMERGE]]89;90entry:91 %alloca = alloca half92 br i1 %cond, label %BB0, label %BB193BB0:94 store half %a, ptr %alloca95 br label %sink96BB1:97 store i16 %b, ptr %alloca98 br label %sink99sink:100 %val = load half, ptr %alloca101 ret half %val102}103 104define i32 @diff_types_diff_width_no_merge(i1 %cond, i32 %a, i64 %b) {105; CHECK-LABEL: @diff_types_diff_width_no_merge(106; CHECK-NEXT: entry:107; CHECK-NEXT: [[ALLOCA:%.*]] = alloca i64, align 8108; CHECK-NEXT: br i1 [[COND:%.*]], label [[IF:%.*]], label [[ELSE:%.*]]109; CHECK: if:110; CHECK-NEXT: store i32 [[A:%.*]], ptr [[ALLOCA]], align 4111; CHECK-NEXT: br label [[SINK:%.*]]112; CHECK: else:113; CHECK-NEXT: store i64 [[B:%.*]], ptr [[ALLOCA]], align 4114; CHECK-NEXT: br label [[SINK]]115; CHECK: sink:116; CHECK-NEXT: [[VAL:%.*]] = load i32, ptr [[ALLOCA]], align 4117; CHECK-NEXT: ret i32 [[VAL]]118;119entry:120 %alloca = alloca i64121 br i1 %cond, label %if, label %else122if:123 store i32 %a, ptr %alloca124 br label %sink125 else:126 store i64 %b, ptr %alloca127 br label %sink128sink:129 %val = load i32, ptr %alloca130 ret i32 %val131}132 133define <4 x i32> @vec_no_merge(i1 %cond, <2 x i32> %a, <4 x i32> %b) {134; CHECK-LABEL: @vec_no_merge(135; CHECK-NEXT: entry:136; CHECK-NEXT: [[ALLOCA:%.*]] = alloca i64, align 8137; CHECK-NEXT: br i1 [[COND:%.*]], label [[IF:%.*]], label [[ELSE:%.*]]138; CHECK: if:139; CHECK-NEXT: store <2 x i32> [[A:%.*]], ptr [[ALLOCA]], align 8140; CHECK-NEXT: br label [[SINK:%.*]]141; CHECK: else:142; CHECK-NEXT: store <4 x i32> [[B:%.*]], ptr [[ALLOCA]], align 16143; CHECK-NEXT: br label [[SINK]]144; CHECK: sink:145; CHECK-NEXT: [[VAL:%.*]] = load <4 x i32>, ptr [[ALLOCA]], align 16146; CHECK-NEXT: ret <4 x i32> [[VAL]]147;148entry:149 %alloca = alloca i64150 br i1 %cond, label %if, label %else151if:152 store <2 x i32> %a, ptr %alloca153 br label %sink154else:155 store <4 x i32> %b, ptr %alloca156 br label %sink157sink:158 %val = load <4 x i32>, ptr %alloca159 ret <4 x i32> %val160}161 162%struct.half = type { half };163 164define %struct.half @one_elem_struct_merge(i1 %cond, %struct.half %a, half %b) {165; CHECK-LABEL: @one_elem_struct_merge(166; CHECK-NEXT: entry:167; CHECK-NEXT: br i1 [[COND:%.*]], label [[BB0:%.*]], label [[BB1:%.*]]168; CHECK: BB0:169; CHECK-NEXT: br label [[SINK:%.*]]170; CHECK: BB1:171; CHECK-NEXT: [[TMP0:%.*]] = insertvalue [[STRUCT_HALF:%.*]] poison, half [[B:%.*]], 0172; CHECK-NEXT: br label [[SINK]]173; CHECK: sink:174; CHECK-NEXT: [[VAL1_MERGED:%.*]] = phi [[STRUCT_HALF]] [ [[A:%.*]], [[BB0]] ], [ [[TMP0]], [[BB1]] ]175; CHECK-NEXT: ret [[STRUCT_HALF]] [[VAL1_MERGED]]176;177entry:178 %alloca = alloca i64179 br i1 %cond, label %BB0, label %BB1180BB0:181 store %struct.half %a, ptr %alloca182 br label %sink183BB1:184 store half %b, ptr %alloca185 br label %sink186sink:187 %val = load %struct.half, ptr %alloca188 ret %struct.half %val189}190 191%struct.tup = type { half, i32 };192 193define %struct.tup @multi_elem_struct_no_merge(i1 %cond, %struct.tup %a, half %b) {194; CHECK-LABEL: @multi_elem_struct_no_merge(195; CHECK-NEXT: entry:196; CHECK-NEXT: [[ALLOCA:%.*]] = alloca i64, align 8197; CHECK-NEXT: br i1 [[COND:%.*]], label [[IF:%.*]], label [[ELSE:%.*]]198; CHECK: if:199; CHECK-NEXT: store [[STRUCT_TUP:%.*]] [[A:%.*]], ptr [[ALLOCA]], align 4200; CHECK-NEXT: br label [[SINK:%.*]]201; CHECK: else:202; CHECK-NEXT: store half [[B:%.*]], ptr [[ALLOCA]], align 2203; CHECK-NEXT: br label [[SINK]]204; CHECK: sink:205; CHECK-NEXT: [[VAL:%.*]] = load [[STRUCT_TUP]], ptr [[ALLOCA]], align 4206; CHECK-NEXT: ret [[STRUCT_TUP]] [[VAL]]207;208entry:209 %alloca = alloca i64210 br i1 %cond, label %if, label %else211if:212 store %struct.tup %a, ptr %alloca213 br label %sink214else:215 store half %b, ptr %alloca216 br label %sink217sink:218 %val = load %struct.tup, ptr %alloca219 ret %struct.tup %val220}221 222define i16 @same_types_diff_align_no_merge(i1 %cond, i16 %a, i16 %b) {223; CHECK-LABEL: @same_types_diff_align_no_merge(224; CHECK-NEXT: entry:225; CHECK-NEXT: [[ALLOCA:%.*]] = alloca i16, align 4226; CHECK-NEXT: br i1 [[COND:%.*]], label [[BB0:%.*]], label [[BB1:%.*]]227; CHECK: BB0:228; CHECK-NEXT: store i16 [[A:%.*]], ptr [[ALLOCA]], align 8229; CHECK-NEXT: br label [[SINK:%.*]]230; CHECK: BB1:231; CHECK-NEXT: store i16 [[B:%.*]], ptr [[ALLOCA]], align 4232; CHECK-NEXT: br label [[SINK]]233; CHECK: sink:234; CHECK-NEXT: [[VAL:%.*]] = load i16, ptr [[ALLOCA]], align 2235; CHECK-NEXT: ret i16 [[VAL]]236;237entry:238 %alloca = alloca i16, align 4239 br i1 %cond, label %BB0, label %BB1240BB0:241 store i16 %a, ptr %alloca, align 8242 br label %sink243BB1:244 store i16 %b, ptr %alloca, align 4245 br label %sink246sink:247 %val = load i16, ptr %alloca248 ret i16 %val249}250 251define i64 @ptrtoint_merge(i1 %cond, i64 %a, ptr %b) {252; CHECK-LABEL: @ptrtoint_merge(253; CHECK-NEXT: entry:254; CHECK-NEXT: [[ALLOCA:%.*]] = alloca ptr, align 8255; CHECK-NEXT: br i1 [[COND:%.*]], label [[BB0:%.*]], label [[BB1:%.*]]256; CHECK: BB0:257; CHECK-NEXT: store i64 [[A:%.*]], ptr [[ALLOCA]], align 4258; CHECK-NEXT: br label [[SINK:%.*]]259; CHECK: BB1:260; CHECK-NEXT: store ptr [[B:%.*]], ptr [[ALLOCA]], align 8261; CHECK-NEXT: br label [[SINK]]262; CHECK: sink:263; CHECK-NEXT: [[VAL:%.*]] = load i64, ptr [[ALLOCA]], align 4264; CHECK-NEXT: ret i64 [[VAL]]265;266entry:267 %alloca = alloca ptr268 br i1 %cond, label %BB0, label %BB1269BB0:270 store i64 %a, ptr %alloca271 br label %sink272BB1:273 store ptr %b, ptr %alloca274 br label %sink275sink:276 %val = load i64, ptr %alloca277 ret i64 %val278}279 280define ptr @inttoptr_merge(i1 %cond, i64 %a, ptr %b) {281; CHECK-LABEL: @inttoptr_merge(282; CHECK-NEXT: entry:283; CHECK-NEXT: br i1 [[COND:%.*]], label [[BB0:%.*]], label [[BB1:%.*]]284; CHECK: BB0:285; CHECK-NEXT: [[TMP0:%.*]] = inttoptr i64 [[A:%.*]] to ptr286; CHECK-NEXT: br label [[SINK:%.*]]287; CHECK: BB1:288; CHECK-NEXT: br label [[SINK]]289; CHECK: sink:290; CHECK-NEXT: [[STOREMERGE:%.*]] = phi ptr [ [[B:%.*]], [[BB1]] ], [ [[TMP0]], [[BB0]] ]291; CHECK-NEXT: ret ptr [[STOREMERGE]]292;293entry:294 %alloca = alloca ptr295 br i1 %cond, label %BB0, label %BB1296BB0:297 store i64 %a, ptr %alloca, align 8298 br label %sink299BB1:300 store ptr %b, ptr %alloca, align 8301 br label %sink302sink:303 %val = load ptr, ptr %alloca304 ret ptr %val305}306 307 308define void @pr46688(i1 %cond, i32 %x, i16 %d, ptr %p1, ptr %p2) {309; CHECK-LABEL: @pr46688(310; CHECK-NEXT: entry:311; CHECK-NEXT: br i1 [[COND:%.*]], label [[IF:%.*]], label [[ELSE:%.*]]312; CHECK: if:313; CHECK-NEXT: br label [[EXIT:%.*]]314; CHECK: else:315; CHECK-NEXT: br label [[EXIT]]316; CHECK: exit:317; CHECK-NEXT: [[DONV_PN:%.*]] = zext i16 [[D:%.*]] to i32318; CHECK-NEXT: [[THR_PN:%.*]] = lshr i32 [[DONV_PN]], [[X:%.*]]319; CHECK-NEXT: [[THR1_PN:%.*]] = lshr i32 [[THR_PN]], [[X]]320; CHECK-NEXT: [[THR2_PN:%.*]] = lshr i32 [[THR1_PN]], [[X]]321; CHECK-NEXT: [[STOREMERGE:%.*]] = lshr i32 [[THR2_PN]], [[X]]322; CHECK-NEXT: [[STOREMERGE1:%.*]] = trunc nuw i32 [[STOREMERGE]] to i16323; CHECK-NEXT: store i16 [[STOREMERGE1]], ptr [[P1:%.*]], align 2324; CHECK-NEXT: store i32 [[STOREMERGE]], ptr [[P2:%.*]], align 4325; CHECK-NEXT: ret void326;327entry:328 br i1 %cond, label %if, label %else329 330if:331 %conv = zext i16 %d to i32332 %shr = lshr i32 %conv, %x333 %shr1 = lshr i32 %shr, %x334 %shr2 = lshr i32 %shr1, %x335 %shr3 = lshr i32 %shr2, %x336 %conv4 = trunc i32 %shr3 to i16337 store i16 %conv4, ptr %p1, align 2338 %conv5 = and i32 %shr3, 65535339 store i32 %conv5, ptr %p2, align 4340 br label %exit341 342else:343 %donv = zext i16 %d to i32344 %thr = lshr i32 %donv, %x345 %thr1 = lshr i32 %thr, %x346 %thr2 = lshr i32 %thr1, %x347 %thr3 = lshr i32 %thr2, %x348 %donv4 = trunc i32 %thr3 to i16349 store i16 %donv4, ptr %p1, align 2350 store i32 %thr3, ptr %p2, align 4351 br label %exit352 353exit:354 ret void355}356