1496 lines · plain
1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --version 52; RUN: opt < %s -passes=instcombine -S | FileCheck %s3 4define i32 @fold(i32 %x) {5; CHECK-LABEL: define i32 @fold(6; CHECK-SAME: i32 [[X:%.*]]) {7; CHECK-NEXT: [[Y:%.*]] = freeze i32 [[X]]8; CHECK-NEXT: ret i32 [[Y]]9;10 %y = freeze i32 %x11 %z = freeze i32 %y12 ret i32 %z13}14 15define i32 @make_const() {16; CHECK-LABEL: define i32 @make_const() {17; CHECK-NEXT: ret i32 1018;19 %x = freeze i32 1020 ret i32 %x21}22 23define i32 @and_freeze_undef(i32 %x) {24; CHECK-LABEL: define i32 @and_freeze_undef(25; CHECK-SAME: i32 [[X:%.*]]) {26; CHECK-NEXT: ret i32 027;28 %f = freeze i32 undef29 %res = and i32 %x, %f30 ret i32 %res31}32 33declare void @use_i32(i32)34declare void @use_p32(ptr)35 36define i32 @and_freeze_undef_multipleuses(i32 %x) {37; CHECK-LABEL: define i32 @and_freeze_undef_multipleuses(38; CHECK-SAME: i32 [[X:%.*]]) {39; CHECK-NEXT: call void @use_i32(i32 0)40; CHECK-NEXT: ret i32 041;42 %f = freeze i32 undef43 %res = and i32 %x, %f44 call void @use_i32(i32 %f)45 ret i32 %res46}47 48define i32 @or_freeze_undef(i32 %x) {49; CHECK-LABEL: define i32 @or_freeze_undef(50; CHECK-SAME: i32 [[X:%.*]]) {51; CHECK-NEXT: ret i32 -152;53 %f = freeze i32 undef54 %res = or i32 %x, %f55 ret i32 %res56}57 58define i32 @or_freeze_undef_multipleuses(i32 %x) {59; CHECK-LABEL: define i32 @or_freeze_undef_multipleuses(60; CHECK-SAME: i32 [[X:%.*]]) {61; CHECK-NEXT: call void @use_i32(i32 0)62; CHECK-NEXT: ret i32 [[X]]63;64 %f = freeze i32 undef65 %res = or i32 %x, %f66 call void @use_i32(i32 %f)67 ret i32 %res68}69 70declare void @use_i32_i1(i32, i1)71 72define void @or_select_multipleuses(i32 %x, i1 %y) {73; CHECK-LABEL: define void @or_select_multipleuses(74; CHECK-SAME: i32 [[X:%.*]], i1 [[Y:%.*]]) {75; CHECK-NEXT: call void @use_i32_i1(i32 32, i1 [[Y]])76; CHECK-NEXT: ret void77;78 %f = freeze i1 undef79 %a = select i1 %f, i32 %x, i32 32 ; prefers %f to be false80 %b = or i1 %f, %y ; prefers %f to be true81 call void @use_i32_i1(i32 %a, i1 %b)82 ret void83}84 85define void @or_select_multipleuses_logical(i32 %x, i1 %y) {86; CHECK-LABEL: define void @or_select_multipleuses_logical(87; CHECK-SAME: i32 [[X:%.*]], i1 [[Y:%.*]]) {88; CHECK-NEXT: call void @use_i32_i1(i32 32, i1 [[Y]])89; CHECK-NEXT: ret void90;91 %f = freeze i1 undef92 %a = select i1 %f, i32 %x, i32 32 ; prefers %f to be false93 %b = select i1 %f, i1 true, i1 %y ; prefers %f to be true94 call void @use_i32_i1(i32 %a, i1 %b)95 ret void96}97 98define <3 x i4> @partial_undef_vec() {99; CHECK-LABEL: define <3 x i4> @partial_undef_vec() {100; CHECK-NEXT: ret <3 x i4> splat (i4 1)101;102 %f = freeze <3 x i4> <i4 poison, i4 1, i4 undef>103 ret <3 x i4> %f104}105 106; Move the freeze forward to prevent poison from spreading.107 108define i32 @early_freeze_test1(i32 %x, i32 %y) {109; CHECK-LABEL: define i32 @early_freeze_test1(110; CHECK-SAME: i32 [[X:%.*]], i32 [[Y:%.*]]) {111; CHECK-NEXT: [[X_FR:%.*]] = freeze i32 [[X]]112; CHECK-NEXT: [[Y_FR:%.*]] = freeze i32 [[Y]]113; CHECK-NEXT: [[V1:%.*]] = add i32 [[X_FR]], [[Y_FR]]114; CHECK-NEXT: [[V2:%.*]] = shl i32 [[V1]], 1115; CHECK-NEXT: [[V3:%.*]] = and i32 [[V2]], 2116; CHECK-NEXT: ret i32 [[V3]]117;118 %v1 = add i32 %x, %y119 %v2 = shl i32 %v1, 1120 %v3 = and i32 %v2, 2121 %v3.fr = freeze i32 %v3122 ret i32 %v3.fr123}124 125define i1 @early_freeze_test2(ptr %ptr) {126; CHECK-LABEL: define i1 @early_freeze_test2(127; CHECK-SAME: ptr [[PTR:%.*]]) {128; CHECK-NEXT: [[V1:%.*]] = load i32, ptr [[PTR]], align 4129; CHECK-NEXT: [[V1_FR:%.*]] = freeze i32 [[V1]]130; CHECK-NEXT: [[V2:%.*]] = and i32 [[V1_FR]], 1131; CHECK-NEXT: [[COND:%.*]] = icmp eq i32 [[V2]], 0132; CHECK-NEXT: ret i1 [[COND]]133;134 %v1 = load i32, ptr %ptr135 %v2 = and i32 %v1, 1136 %cond = icmp eq i32 %v2, 0137 %cond.fr = freeze i1 %cond138 ret i1 %cond.fr139}140 141define i32 @early_freeze_test3(i32 %v1) {142; CHECK-LABEL: define i32 @early_freeze_test3(143; CHECK-SAME: i32 [[V1:%.*]]) {144; CHECK-NEXT: [[V1_FR:%.*]] = freeze i32 [[V1]]145; CHECK-NEXT: [[V2:%.*]] = shl i32 [[V1_FR]], 1146; CHECK-NEXT: [[V4:%.*]] = add i32 [[V2]], 3147; CHECK-NEXT: ret i32 [[V4]]148;149 %v2 = shl i32 %v1, 1150 %v3 = add nuw i32 %v2, 2151 %v4 = or i32 %v3, 1152 %v4.fr = freeze i32 %v4153 ret i32 %v4.fr154}155 156define i32 @early_freeze_test4(i32 %v1) {157; CHECK-LABEL: define i32 @early_freeze_test4(158; CHECK-SAME: i32 [[V1:%.*]]) {159; CHECK-NEXT: [[V1_FR:%.*]] = freeze i32 [[V1]]160; CHECK-NEXT: [[V2:%.*]] = mul i32 [[V1_FR]], [[V1_FR]]161; CHECK-NEXT: ret i32 [[V2]]162;163 %v2 = mul i32 %v1, %v1164 %v2.fr = freeze i32 %v2165 ret i32 %v2.fr166}167 168; If replace all dominated uses of v to freeze(v).169 170define void @freeze_dominated_uses_test1(i32 %v) {171; CHECK-LABEL: define void @freeze_dominated_uses_test1(172; CHECK-SAME: i32 [[V:%.*]]) {173; CHECK-NEXT: [[V_FR:%.*]] = freeze i32 [[V]]174; CHECK-NEXT: call void @use_i32(i32 [[V_FR]])175; CHECK-NEXT: call void @use_i32(i32 [[V_FR]])176; CHECK-NEXT: ret void177;178 %v.fr = freeze i32 %v179 call void @use_i32(i32 %v)180 call void @use_i32(i32 %v.fr)181 ret void182}183 184define void @freeze_dominated_uses_test2(i32 %v) {185; CHECK-LABEL: define void @freeze_dominated_uses_test2(186; CHECK-SAME: i32 [[V:%.*]]) {187; CHECK-NEXT: [[ENTRY:.*:]]188; CHECK-NEXT: [[A:%.*]] = alloca i32, align 4189; CHECK-NEXT: [[V_FR:%.*]] = freeze i32 [[V]]190; CHECK-NEXT: call void @use_p32(ptr nonnull [[A]])191; CHECK-NEXT: call void @use_i32(i32 [[V_FR]])192; CHECK-NEXT: [[COND:%.*]] = icmp eq i32 [[V_FR]], 0193; CHECK-NEXT: br i1 [[COND]], label %[[BB_0:.*]], label %[[BB_1:.*]]194; CHECK: [[BB_0]]:195; CHECK-NEXT: call void @use_i32(i32 [[V_FR]])196; CHECK-NEXT: call void @use_i32(i32 [[V_FR]])197; CHECK-NEXT: br label %[[END:.*]]198; CHECK: [[BB_1]]:199; CHECK-NEXT: call void @use_i32(i32 [[V_FR]])200; CHECK-NEXT: br label %[[END]]201; CHECK: [[END]]:202; CHECK-NEXT: ret void203;204entry:205 %a = alloca i32206 call void @use_p32(ptr %a)207 call void @use_i32(i32 %v)208 %cond = icmp eq i32 %v, 0209 br i1 %cond, label %bb.0, label %bb.1210 211bb.0:212 %v.fr = freeze i32 %v213 call void @use_i32(i32 %v.fr)214 call void @use_i32(i32 %v)215 br label %end216 217bb.1:218 call void @use_i32(i32 %v)219 br label %end220 221end:222 ret void223}224 225; If there is a duplicate freeze, it will be removed.226 227define void @freeze_dominated_uses_test3(i32 %v, i1 %cond) {228; CHECK-LABEL: define void @freeze_dominated_uses_test3(229; CHECK-SAME: i32 [[V:%.*]], i1 [[COND:%.*]]) {230; CHECK-NEXT: [[ENTRY:.*:]]231; CHECK-NEXT: [[V_FR1:%.*]] = freeze i32 [[V]]232; CHECK-NEXT: call void @use_i32(i32 [[V_FR1]])233; CHECK-NEXT: br i1 [[COND]], label %[[BB_0:.*]], label %[[BB_1:.*]]234; CHECK: [[BB_0]]:235; CHECK-NEXT: call void @use_i32(i32 [[V_FR1]])236; CHECK-NEXT: br label %[[END:.*]]237; CHECK: [[BB_1]]:238; CHECK-NEXT: call void @use_i32(i32 [[V_FR1]])239; CHECK-NEXT: br label %[[END]]240; CHECK: [[END]]:241; CHECK-NEXT: ret void242;243entry:244 %v.fr1 = freeze i32 %v245 call void @use_i32(i32 %v.fr1)246 br i1 %cond, label %bb.0, label %bb.1247 248bb.0:249 %v.fr2 = freeze i32 %v250 call void @use_i32(i32 %v.fr2)251 br label %end252 253bb.1:254 call void @use_i32(i32 %v)255 br label %end256 257end:258 ret void259}260 261declare i32 @__CxxFrameHandler3(...)262 263define void @freeze_dominated_uses_catchswitch(i1 %c, i32 %x) personality ptr @__CxxFrameHandler3 {264; CHECK-LABEL: define void @freeze_dominated_uses_catchswitch(265; CHECK-SAME: i1 [[C:%.*]], i32 [[X:%.*]]) personality ptr @__CxxFrameHandler3 {266; CHECK-NEXT: [[ENTRY:.*:]]267; CHECK-NEXT: br i1 [[C]], label %[[IF_THEN:.*]], label %[[IF_ELSE:.*]]268; CHECK: [[IF_THEN]]:269; CHECK-NEXT: invoke void @use_i32(i32 0)270; CHECK-NEXT: to label %[[CLEANUP:.*]] unwind label %[[CATCH_DISPATCH:.*]]271; CHECK: [[IF_ELSE]]:272; CHECK-NEXT: invoke void @use_i32(i32 1)273; CHECK-NEXT: to label %[[CLEANUP]] unwind label %[[CATCH_DISPATCH]]274; CHECK: [[CATCH_DISPATCH]]:275; CHECK-NEXT: [[PHI:%.*]] = phi i32 [ 0, %[[IF_THEN]] ], [ [[X]], %[[IF_ELSE]] ]276; CHECK-NEXT: [[CS:%.*]] = catchswitch within none [label %[[CATCH:.*]], label %catch2] unwind to caller277; CHECK: [[CATCH]]:278; CHECK-NEXT: [[CP:%.*]] = catchpad within [[CS]] [ptr null, i32 64, ptr null]279; CHECK-NEXT: [[PHI_FREEZE:%.*]] = freeze i32 [[PHI]]280; CHECK-NEXT: call void @use_i32(i32 [[PHI_FREEZE]]) [ "funclet"(token [[CP]]) ]281; CHECK-NEXT: unreachable282; CHECK: [[CATCH2:.*:]]283; CHECK-NEXT: [[CP2:%.*]] = catchpad within [[CS]] [ptr null, i32 64, ptr null]284; CHECK-NEXT: call void @use_i32(i32 [[PHI]]) [ "funclet"(token [[CP2]]) ]285; CHECK-NEXT: unreachable286; CHECK: [[CLEANUP]]:287; CHECK-NEXT: ret void288;289entry:290 br i1 %c, label %if.then, label %if.else291 292if.then:293 invoke void @use_i32(i32 0)294 to label %cleanup unwind label %catch.dispatch295 296if.else:297 invoke void @use_i32(i32 1)298 to label %cleanup unwind label %catch.dispatch299 300catch.dispatch:301 %phi = phi i32 [ 0, %if.then ], [ %x, %if.else ]302 %cs = catchswitch within none [label %catch, label %catch2] unwind to caller303 304catch:305 %cp = catchpad within %cs [ptr null, i32 64, ptr null]306 %phi.freeze = freeze i32 %phi307 call void @use_i32(i32 %phi.freeze) [ "funclet"(token %cp) ]308 unreachable309 310catch2:311 %cp2 = catchpad within %cs [ptr null, i32 64, ptr null]312 call void @use_i32(i32 %phi) [ "funclet"(token %cp2) ]313 unreachable314 315cleanup:316 ret void317}318 319declare i32 @get_i32()320 321define i32 @freeze_use_in_different_branches(i1 %c) {322; CHECK-LABEL: define i32 @freeze_use_in_different_branches(323; CHECK-SAME: i1 [[C:%.*]]) {324; CHECK-NEXT: [[ENTRY:.*:]]325; CHECK-NEXT: [[X:%.*]] = call i32 @get_i32()326; CHECK-NEXT: [[FR:%.*]] = freeze i32 [[X]]327; CHECK-NEXT: call void @use_i32(i32 0)328; CHECK-NEXT: br i1 [[C]], label %[[IF:.*]], label %[[ELSE:.*]]329; CHECK: [[IF]]:330; CHECK-NEXT: call void @use_i32(i32 [[FR]])331; CHECK-NEXT: ret i32 0332; CHECK: [[ELSE]]:333; CHECK-NEXT: call void @use_i32(i32 [[FR]])334; CHECK-NEXT: call void @use_i32(i32 [[FR]])335; CHECK-NEXT: ret i32 1336;337entry:338 %x = call i32 @get_i32()339 call void @use_i32(i32 0)340 br i1 %c, label %if, label %else341 342if:343 call void @use_i32(i32 %x)344 ret i32 0345 346else:347 call void @use_i32(i32 %x)348 %fr = freeze i32 %x349 call void @use_i32(i32 %fr)350 ret i32 1351}352 353define i32 @freeze_phi_use(i1 %c) {354; CHECK-LABEL: define i32 @freeze_phi_use(355; CHECK-SAME: i1 [[C:%.*]]) {356; CHECK-NEXT: [[ENTRY:.*]]:357; CHECK-NEXT: [[X:%.*]] = call i32 @get_i32()358; CHECK-NEXT: [[FR:%.*]] = freeze i32 [[X]]359; CHECK-NEXT: call void @use_i32(i32 0)360; CHECK-NEXT: br i1 [[C]], label %[[IF:.*]], label %[[JOIN:.*]]361; CHECK: [[IF]]:362; CHECK-NEXT: br label %[[JOIN]]363; CHECK: [[JOIN]]:364; CHECK-NEXT: [[PHI:%.*]] = phi i32 [ [[FR]], %[[IF]] ], [ 0, %[[ENTRY]] ]365; CHECK-NEXT: call void @use_i32(i32 [[FR]])366; CHECK-NEXT: ret i32 [[PHI]]367;368entry:369 %x = call i32 @get_i32()370 call void @use_i32(i32 0)371 br i1 %c, label %if, label %join372 373if:374 br label %join375 376join:377 %phi = phi i32 [ %x, %if ], [ 0, %entry ]378 %fr = freeze i32 %x379 call void @use_i32(i32 %fr)380 ret i32 %phi381}382 383define i32 @freeze_phi_followed_by_phi(i1 %c, i32 %y, i32 %z) {384; CHECK-LABEL: define i32 @freeze_phi_followed_by_phi(385; CHECK-SAME: i1 [[C:%.*]], i32 [[Y:%.*]], i32 [[Z:%.*]]) {386; CHECK-NEXT: [[ENTRY:.*]]:387; CHECK-NEXT: br i1 [[C]], label %[[IF:.*]], label %[[JOIN:.*]]388; CHECK: [[IF]]:389; CHECK-NEXT: br label %[[JOIN]]390; CHECK: [[JOIN]]:391; CHECK-NEXT: [[X:%.*]] = phi i32 [ [[Y]], %[[IF]] ], [ [[Z]], %[[ENTRY]] ]392; CHECK-NEXT: [[PHI:%.*]] = phi i32 [ [[Z]], %[[IF]] ], [ [[Y]], %[[ENTRY]] ]393; CHECK-NEXT: [[FR:%.*]] = freeze i32 [[X]]394; CHECK-NEXT: call void @use_i32(i32 [[FR]])395; CHECK-NEXT: call void @use_i32(i32 [[FR]])396; CHECK-NEXT: ret i32 [[PHI]]397;398entry:399 br i1 %c, label %if, label %join400 401if:402 br label %join403 404join:405 %x = phi i32 [ %y, %if ], [ %z, %entry ]406 %phi = phi i32 [ %z, %if ], [ %y, %entry ]407 call void @use_i32(i32 %x)408 %fr = freeze i32 %x409 call void @use_i32(i32 %fr)410 ret i32 %phi411}412 413define i32 @freeze_invoke_use_in_phi(i1 %c) personality ptr undef {414; CHECK-LABEL: define i32 @freeze_invoke_use_in_phi(415; CHECK-SAME: i1 [[C:%.*]]) personality ptr undef {416; CHECK-NEXT: [[ENTRY:.*]]:417; CHECK-NEXT: [[X:%.*]] = invoke i32 @get_i32()418; CHECK-NEXT: to label %[[INVOKE_CONT:.*]] unwind label %[[INVOKE_UNWIND:.*]]419; CHECK: [[INVOKE_CONT]]:420; CHECK-NEXT: [[PHI:%.*]] = phi i32 [ [[X]], %[[ENTRY]] ], [ 0, %[[INVOKE_CONT]] ]421; CHECK-NEXT: [[FR:%.*]] = freeze i32 [[X]]422; CHECK-NEXT: call void @use_i32(i32 [[FR]])423; CHECK-NEXT: call void @use_i32(i32 [[PHI]])424; CHECK-NEXT: br label %[[INVOKE_CONT]]425; CHECK: [[INVOKE_UNWIND]]:426; CHECK-NEXT: [[TMP0:%.*]] = landingpad i8427; CHECK-NEXT: cleanup428; CHECK-NEXT: unreachable429;430entry:431 %x = invoke i32 @get_i32()432 to label %invoke.cont unwind label %invoke.unwind433 434invoke.cont:435 %phi = phi i32 [ %x, %entry ], [ 0, %invoke.cont ]436 %fr = freeze i32 %x437 call void @use_i32(i32 %fr)438 call void @use_i32(i32 %phi)439 br label %invoke.cont440 441invoke.unwind:442 landingpad i8 cleanup443 unreachable444}445 446define i32 @freeze_invoke_use_after_phi(i1 %c) personality ptr undef {447; CHECK-LABEL: define i32 @freeze_invoke_use_after_phi(448; CHECK-SAME: i1 [[C:%.*]]) personality ptr undef {449; CHECK-NEXT: [[ENTRY:.*]]:450; CHECK-NEXT: [[X:%.*]] = invoke i32 @get_i32()451; CHECK-NEXT: to label %[[INVOKE_CONT:.*]] unwind label %[[INVOKE_UNWIND:.*]]452; CHECK: [[INVOKE_CONT]]:453; CHECK-NEXT: [[PHI:%.*]] = phi i32 [ [[X]], %[[ENTRY]] ], [ 0, %[[INVOKE_CONT]] ]454; CHECK-NEXT: [[FR:%.*]] = freeze i32 [[X]]455; CHECK-NEXT: call void @use_i32(i32 [[FR]])456; CHECK-NEXT: call void @use_i32(i32 [[FR]])457; CHECK-NEXT: call void @use_i32(i32 [[PHI]])458; CHECK-NEXT: br label %[[INVOKE_CONT]]459; CHECK: [[INVOKE_UNWIND]]:460; CHECK-NEXT: [[TMP0:%.*]] = landingpad i8461; CHECK-NEXT: cleanup462; CHECK-NEXT: unreachable463;464entry:465 %x = invoke i32 @get_i32()466 to label %invoke.cont unwind label %invoke.unwind467 468invoke.cont:469 %phi = phi i32 [ %x, %entry ], [ 0, %invoke.cont ]470 call void @use_i32(i32 %x)471 %fr = freeze i32 %x472 call void @use_i32(i32 %fr)473 call void @use_i32(i32 %phi)474 br label %invoke.cont475 476invoke.unwind:477 landingpad i8 cleanup478 unreachable479}480 481define i32 @freeze_callbr_use_after_phi(i1 %c) {482; CHECK-LABEL: define i32 @freeze_callbr_use_after_phi(483; CHECK-SAME: i1 [[C:%.*]]) {484; CHECK-NEXT: [[ENTRY:.*]]:485; CHECK-NEXT: [[X:%.*]] = callbr i32 asm sideeffect "", "=r"() #[[ATTR1:[0-9]+]]486; CHECK-NEXT: to label %[[CALLBR_CONT:.*]] []487; CHECK: [[CALLBR_CONT]]:488; CHECK-NEXT: [[PHI:%.*]] = phi i32 [ [[X]], %[[ENTRY]] ], [ 0, %[[CALLBR_CONT]] ]489; CHECK-NEXT: call void @use_i32(i32 [[X]])490; CHECK-NEXT: [[FR:%.*]] = freeze i32 [[X]]491; CHECK-NEXT: call void @use_i32(i32 [[FR]])492; CHECK-NEXT: call void @use_i32(i32 [[PHI]])493; CHECK-NEXT: br label %[[CALLBR_CONT]]494;495entry:496 %x = callbr i32 asm sideeffect "", "=r"()497 to label %callbr.cont []498 499callbr.cont:500 %phi = phi i32 [ %x, %entry ], [ 0, %callbr.cont ]501 call void @use_i32(i32 %x)502 %fr = freeze i32 %x503 call void @use_i32(i32 %fr)504 call void @use_i32(i32 %phi)505 br label %callbr.cont506}507 508define i1 @combine_and_after_freezing_uses(i32 %x) {509; CHECK-LABEL: define i1 @combine_and_after_freezing_uses(510; CHECK-SAME: i32 [[X:%.*]]) {511; CHECK-NEXT: [[X_FR:%.*]] = freeze i32 [[X]]512; CHECK-NEXT: [[TMP1:%.*]] = and i32 [[X_FR]], 15513; CHECK-NEXT: [[AND:%.*]] = icmp eq i32 [[TMP1]], 15514; CHECK-NEXT: ret i1 [[AND]]515;516 %and1 = and i32 %x, 4517 %cmp1 = icmp ne i32 %and1, 0518 %x.fr = freeze i32 %x519 %and2 = and i32 %x.fr, 11520 %cmp2 = icmp eq i32 %and2, 11521 %and = and i1 %cmp1, %cmp2522 ret i1 %and523}524 525declare i1 @mock_use(i64, i64)526define i1 @fully_propagate_freeze(i32 %0, i32 noundef %1) {527; CHECK-LABEL: define i1 @fully_propagate_freeze(528; CHECK-SAME: i32 [[TMP0:%.*]], i32 noundef [[TMP1:%.*]]) {529; CHECK-NEXT: [[DOTFR:%.*]] = freeze i32 [[TMP0]]530; CHECK-NEXT: [[DR:%.*]] = lshr i32 [[DOTFR]], 2531; CHECK-NEXT: [[IDX1:%.*]] = zext nneg i32 [[DR]] to i64532; CHECK-NEXT: [[ADD:%.*]] = add nuw nsw i32 [[DR]], 1533; CHECK-NEXT: [[CMP:%.*]] = icmp slt i32 [[ADD]], [[TMP1]]534; CHECK-NEXT: [[IDX2:%.*]] = zext nneg i32 [[DR]] to i64535; CHECK-NEXT: [[V:%.*]] = call i1 @mock_use(i64 [[IDX1]], i64 [[IDX2]])536; CHECK-NEXT: [[RET:%.*]] = and i1 [[V]], [[CMP]]537; CHECK-NEXT: ret i1 [[RET]]538;539 %dr = lshr i32 %0, 2540 %idx1 = zext i32 %dr to i64541 %add = add i32 %dr, 1542 %cmp = icmp slt i32 %add, %1543 %cmp.fr = freeze i1 %cmp544 %idx2 = zext i32 %dr to i64545 %v = call i1 @mock_use(i64 %idx1, i64 %idx2)546 %ret = and i1 %v, %cmp.fr547 ret i1 %ret548}549 550define i32 @propagate_drop_flags_add(i32 %arg) {551; CHECK-LABEL: define i32 @propagate_drop_flags_add(552; CHECK-SAME: i32 [[ARG:%.*]]) {553; CHECK-NEXT: [[ARG_FR:%.*]] = freeze i32 [[ARG]]554; CHECK-NEXT: [[V1:%.*]] = add i32 [[ARG_FR]], 2555; CHECK-NEXT: ret i32 [[V1]]556;557 %v1 = add nsw nuw i32 %arg, 2558 %v1.fr = freeze i32 %v1559 ret i32 %v1.fr560}561 562define i32 @propagate_drop_flags_add_foldaway(i32 noundef %arg) {563; CHECK-LABEL: define i32 @propagate_drop_flags_add_foldaway(564; CHECK-SAME: i32 noundef [[ARG:%.*]]) {565; CHECK-NEXT: [[V1:%.*]] = add i32 [[ARG]], 2566; CHECK-NEXT: ret i32 [[V1]]567;568 %v1 = add nsw nuw i32 %arg, 2569 %v1.fr = freeze i32 %v1570 ret i32 %v1.fr571}572 573define i32 @propagate_drop_flags_sub(i32 %arg) {574; CHECK-LABEL: define i32 @propagate_drop_flags_sub(575; CHECK-SAME: i32 [[ARG:%.*]]) {576; CHECK-NEXT: [[ARG_FR:%.*]] = freeze i32 [[ARG]]577; CHECK-NEXT: [[V1:%.*]] = add i32 [[ARG_FR]], -2578; CHECK-NEXT: ret i32 [[V1]]579;580 %v1 = sub nsw nuw i32 %arg, 2581 %v1.fr = freeze i32 %v1582 ret i32 %v1.fr583}584 585define i32 @propagate_drop_flags_mul(i32 %arg) {586; CHECK-LABEL: define i32 @propagate_drop_flags_mul(587; CHECK-SAME: i32 [[ARG:%.*]]) {588; CHECK-NEXT: [[ARG_FR:%.*]] = freeze i32 [[ARG]]589; CHECK-NEXT: [[V1:%.*]] = shl i32 [[ARG_FR]], 1590; CHECK-NEXT: ret i32 [[V1]]591;592 %v1 = mul nsw nuw i32 %arg, 2593 %v1.fr = freeze i32 %v1594 ret i32 %v1.fr595}596 597define i32 @propagate_drop_flags_udiv(i32 %arg) {598; CHECK-LABEL: define i32 @propagate_drop_flags_udiv(599; CHECK-SAME: i32 [[ARG:%.*]]) {600; CHECK-NEXT: [[ARG_FR:%.*]] = freeze i32 [[ARG]]601; CHECK-NEXT: [[V11:%.*]] = lshr i32 [[ARG_FR]], 1602; CHECK-NEXT: ret i32 [[V11]]603;604 %v1 = udiv exact i32 %arg, 2605 %v1.fr = freeze i32 %v1606 ret i32 %v1.fr607}608 609define i32 @propagate_drop_flags_sdiv(i32 %arg) {610; CHECK-LABEL: define i32 @propagate_drop_flags_sdiv(611; CHECK-SAME: i32 [[ARG:%.*]]) {612; CHECK-NEXT: [[ARG_FR:%.*]] = freeze i32 [[ARG]]613; CHECK-NEXT: [[V1:%.*]] = ashr i32 [[ARG_FR]], 1614; CHECK-NEXT: ret i32 [[V1]]615;616 %v1 = sdiv exact i32 %arg, 2617 %v1.fr = freeze i32 %v1618 ret i32 %v1.fr619}620 621define i32 @propagate_drop_shl1(i32 %arg) {622; CHECK-LABEL: define i32 @propagate_drop_shl1(623; CHECK-SAME: i32 [[ARG:%.*]]) {624; CHECK-NEXT: [[ARG_FR:%.*]] = freeze i32 [[ARG]]625; CHECK-NEXT: [[V1:%.*]] = shl i32 [[ARG_FR]], 2626; CHECK-NEXT: ret i32 [[V1]]627;628 %v1 = shl nsw nuw i32 %arg, 2629 %v1.fr = freeze i32 %v1630 ret i32 %v1.fr631}632 633define i32 @propagate_drop_shl2(i32 %arg, i32 %unknown) {634; CHECK-LABEL: define i32 @propagate_drop_shl2(635; CHECK-SAME: i32 [[ARG:%.*]], i32 [[UNKNOWN:%.*]]) {636; CHECK-NEXT: [[V1:%.*]] = shl nuw nsw i32 [[ARG]], [[UNKNOWN]]637; CHECK-NEXT: [[V1_FR:%.*]] = freeze i32 [[V1]]638; CHECK-NEXT: ret i32 [[V1_FR]]639;640 %v1 = shl nsw nuw i32 %arg, %unknown641 %v1.fr = freeze i32 %v1642 ret i32 %v1.fr643}644 645define i32 @propagate_drop_ashr1(i32 %arg) {646; CHECK-LABEL: define i32 @propagate_drop_ashr1(647; CHECK-SAME: i32 [[ARG:%.*]]) {648; CHECK-NEXT: [[ARG_FR:%.*]] = freeze i32 [[ARG]]649; CHECK-NEXT: [[V1:%.*]] = ashr i32 [[ARG_FR]], 2650; CHECK-NEXT: ret i32 [[V1]]651;652 %v1 = ashr exact i32 %arg, 2653 %v1.fr = freeze i32 %v1654 ret i32 %v1.fr655}656 657define i32 @propagate_drop_ashr2(i32 %arg, i32 %unknown) {658; CHECK-LABEL: define i32 @propagate_drop_ashr2(659; CHECK-SAME: i32 [[ARG:%.*]], i32 [[UNKNOWN:%.*]]) {660; CHECK-NEXT: [[V1:%.*]] = ashr exact i32 [[ARG]], [[UNKNOWN]]661; CHECK-NEXT: [[V1_FR:%.*]] = freeze i32 [[V1]]662; CHECK-NEXT: ret i32 [[V1_FR]]663;664 %v1 = ashr exact i32 %arg, %unknown665 %v1.fr = freeze i32 %v1666 ret i32 %v1.fr667}668 669define i32 @propagate_drop_lshr1(i32 %arg) {670; CHECK-LABEL: define i32 @propagate_drop_lshr1(671; CHECK-SAME: i32 [[ARG:%.*]]) {672; CHECK-NEXT: [[ARG_FR:%.*]] = freeze i32 [[ARG]]673; CHECK-NEXT: [[V1:%.*]] = lshr i32 [[ARG_FR]], 2674; CHECK-NEXT: ret i32 [[V1]]675;676 %v1 = lshr exact i32 %arg, 2677 %v1.fr = freeze i32 %v1678 ret i32 %v1.fr679}680 681define i32 @propagate_drop_lshr2(i32 %arg, i32 %unknown) {682; CHECK-LABEL: define i32 @propagate_drop_lshr2(683; CHECK-SAME: i32 [[ARG:%.*]], i32 [[UNKNOWN:%.*]]) {684; CHECK-NEXT: [[V1:%.*]] = lshr exact i32 [[ARG]], [[UNKNOWN]]685; CHECK-NEXT: [[V1_FR:%.*]] = freeze i32 [[V1]]686; CHECK-NEXT: ret i32 [[V1_FR]]687;688 %v1 = lshr exact i32 %arg, %unknown689 %v1.fr = freeze i32 %v1690 ret i32 %v1.fr691}692 693define ptr @propagate_drop_gep1(ptr %arg) {694; CHECK-LABEL: define ptr @propagate_drop_gep1(695; CHECK-SAME: ptr [[ARG:%.*]]) {696; CHECK-NEXT: [[ARG_FR:%.*]] = freeze ptr [[ARG]]697; CHECK-NEXT: [[V1:%.*]] = getelementptr i8, ptr [[ARG_FR]], i64 16698; CHECK-NEXT: ret ptr [[V1]]699;700 %v1 = getelementptr inbounds i8, ptr %arg, i64 16701 %v1.fr = freeze ptr %v1702 ret ptr %v1.fr703}704 705define float @propagate_drop_fneg(float %arg) {706; CHECK-LABEL: define float @propagate_drop_fneg(707; CHECK-SAME: float [[ARG:%.*]]) {708; CHECK-NEXT: [[ARG_FR:%.*]] = freeze float [[ARG]]709; CHECK-NEXT: [[V1:%.*]] = fneg float [[ARG_FR]]710; CHECK-NEXT: ret float [[V1]]711;712 %v1 = fneg ninf nnan float %arg713 %v1.fr = freeze float %v1714 ret float %v1.fr715}716 717 718define float @propagate_drop_fadd(float %arg) {719; CHECK-LABEL: define float @propagate_drop_fadd(720; CHECK-SAME: float [[ARG:%.*]]) {721; CHECK-NEXT: [[ARG_FR:%.*]] = freeze float [[ARG]]722; CHECK-NEXT: [[V1:%.*]] = fadd float [[ARG_FR]], 2.000000e+00723; CHECK-NEXT: ret float [[V1]]724;725 %v1 = fadd ninf nnan float %arg, 2.0726 %v1.fr = freeze float %v1727 ret float %v1.fr728}729 730define float @propagate_drop_fsub(float %arg) {731; CHECK-LABEL: define float @propagate_drop_fsub(732; CHECK-SAME: float [[ARG:%.*]]) {733; CHECK-NEXT: [[ARG_FR:%.*]] = freeze float [[ARG]]734; CHECK-NEXT: [[V1:%.*]] = fadd float [[ARG_FR]], -2.000000e+00735; CHECK-NEXT: ret float [[V1]]736;737 %v1 = fsub ninf nnan float %arg, 2.0738 %v1.fr = freeze float %v1739 ret float %v1.fr740}741 742define float @propagate_drop_fmul(float %arg) {743; CHECK-LABEL: define float @propagate_drop_fmul(744; CHECK-SAME: float [[ARG:%.*]]) {745; CHECK-NEXT: [[ARG_FR:%.*]] = freeze float [[ARG]]746; CHECK-NEXT: [[V1:%.*]] = fmul float [[ARG_FR]], 2.000000e+00747; CHECK-NEXT: ret float [[V1]]748;749 %v1 = fmul ninf nnan float %arg, 2.0750 %v1.fr = freeze float %v1751 ret float %v1.fr752}753 754define float @propagate_drop_fdiv(float %arg) {755; CHECK-LABEL: define float @propagate_drop_fdiv(756; CHECK-SAME: float [[ARG:%.*]]) {757; CHECK-NEXT: [[ARG_FR:%.*]] = freeze float [[ARG]]758; CHECK-NEXT: [[V1:%.*]] = fmul float [[ARG_FR]], 5.000000e-01759; CHECK-NEXT: ret float [[V1]]760;761 %v1 = fdiv ninf nnan float %arg, 2.0762 %v1.fr = freeze float %v1763 ret float %v1.fr764}765 766define float @propagate_drop_frem(float %arg) {767; CHECK-LABEL: define float @propagate_drop_frem(768; CHECK-SAME: float [[ARG:%.*]]) {769; CHECK-NEXT: [[ARG_FR:%.*]] = freeze float [[ARG]]770; CHECK-NEXT: [[V1:%.*]] = frem float [[ARG_FR]], 2.000000e+00771; CHECK-NEXT: ret float [[V1]]772;773 %v1 = frem ninf nnan float %arg, 2.0774 %v1.fr = freeze float %v1775 ret float %v1.fr776}777 778define i1 @propagate_drop_fcmp(float %arg) {779; CHECK-LABEL: define i1 @propagate_drop_fcmp(780; CHECK-SAME: float [[ARG:%.*]]) {781; CHECK-NEXT: [[ARG_FR:%.*]] = freeze float [[ARG]]782; CHECK-NEXT: [[V1:%.*]] = fcmp une float [[ARG_FR]], 2.000000e+00783; CHECK-NEXT: ret i1 [[V1]]784;785 %v1 = fcmp ninf nnan une float %arg, 2.0786 %v1.fr = freeze i1 %v1787 ret i1 %v1.fr788}789 790define float @propagate_drop_fmath_select(i1 %arg) {791; CHECK-LABEL: define float @propagate_drop_fmath_select(792; CHECK-SAME: i1 [[ARG:%.*]]) {793; CHECK-NEXT: [[ARG_FR:%.*]] = freeze i1 [[ARG]]794; CHECK-NEXT: [[V1:%.*]] = select i1 [[ARG_FR]], float 1.000000e+00, float -1.000000e+00795; CHECK-NEXT: ret float [[V1]]796;797 %v1 = select ninf nnan i1 %arg, float 1.0, float -1.0798 %v1.fr = freeze float %v1799 ret float %v1.fr800}801 802define void @fold_phi_noop(i32 noundef %init, i32 %n) {803; CHECK-LABEL: define void @fold_phi_noop(804; CHECK-SAME: i32 noundef [[INIT:%.*]], i32 [[N:%.*]]) {805; CHECK-NEXT: [[ENTRY:.*]]:806; CHECK-NEXT: br label %[[LOOP:.*]]807; CHECK: [[LOOP]]:808; CHECK-NEXT: [[I:%.*]] = phi i32 [ [[INIT]], %[[ENTRY]] ], [ [[I_NEXT:%.*]], %[[LOOP]] ]809; CHECK-NEXT: [[I_NEXT]] = add i32 [[I]], 1810; CHECK-NEXT: [[COND:%.*]] = icmp eq i32 [[I_NEXT]], [[N]]811; CHECK-NEXT: br i1 [[COND]], label %[[LOOP]], label %[[EXIT:.*]]812; CHECK: [[EXIT]]:813; CHECK-NEXT: ret void814;815entry:816 br label %loop817 818loop: ; preds = %loop, %entry819 %i = phi i32 [ %init, %entry ], [ %i.next, %loop ]820 %i.fr = freeze i32 %i821 %i.next = add i32 %i.fr, 1822 %cond = icmp eq i32 %i.next, %n823 br i1 %cond, label %loop, label %exit824 825exit: ; preds = %loop826 ret void827}828 829define void @fold_phi_through(i32 %init, i32 %n) {830; CHECK-LABEL: define void @fold_phi_through(831; CHECK-SAME: i32 [[INIT:%.*]], i32 [[N:%.*]]) {832; CHECK-NEXT: [[ENTRY:.*]]:833; CHECK-NEXT: [[TMP0:%.*]] = freeze i32 [[INIT]]834; CHECK-NEXT: br label %[[LOOP:.*]]835; CHECK: [[LOOP]]:836; CHECK-NEXT: [[I:%.*]] = phi i32 [ [[TMP0]], %[[ENTRY]] ], [ [[I_NEXT:%.*]], %[[LOOP]] ]837; CHECK-NEXT: [[I_NEXT]] = add i32 [[I]], 1838; CHECK-NEXT: [[COND:%.*]] = icmp eq i32 [[I_NEXT]], [[N]]839; CHECK-NEXT: br i1 [[COND]], label %[[LOOP]], label %[[EXIT:.*]]840; CHECK: [[EXIT]]:841; CHECK-NEXT: ret void842;843entry:844 br label %loop845 846loop: ; preds = %loop, %entry847 %i = phi i32 [ %init, %entry ], [ %i.next, %loop ]848 %i.fr = freeze i32 %i849 %i.next = add i32 %i.fr, 1850 %cond = icmp eq i32 %i.next, %n851 br i1 %cond, label %loop, label %exit852 853exit: ; preds = %loop854 ret void855}856 857define void @fold_phi_drop_flags(i32 %init, i32 %n) {858; CHECK-LABEL: define void @fold_phi_drop_flags(859; CHECK-SAME: i32 [[INIT:%.*]], i32 [[N:%.*]]) {860; CHECK-NEXT: [[ENTRY:.*]]:861; CHECK-NEXT: [[INIT_FR:%.*]] = freeze i32 [[INIT]]862; CHECK-NEXT: br label %[[LOOP:.*]]863; CHECK: [[LOOP]]:864; CHECK-NEXT: [[I:%.*]] = phi i32 [ [[INIT_FR]], %[[ENTRY]] ], [ [[I_NEXT:%.*]], %[[LOOP]] ]865; CHECK-NEXT: [[I_NEXT]] = add i32 [[I]], 1866; CHECK-NEXT: [[COND:%.*]] = icmp eq i32 [[I_NEXT]], [[N]]867; CHECK-NEXT: br i1 [[COND]], label %[[LOOP]], label %[[EXIT:.*]]868; CHECK: [[EXIT]]:869; CHECK-NEXT: ret void870;871entry:872 br label %loop873 874loop: ; preds = %loop, %entry875 %i = phi i32 [ %init, %entry ], [ %i.next, %loop ]876 %i.fr = freeze i32 %i877 %i.next = add nsw nuw i32 %i.fr, 1878 %cond = icmp eq i32 %i.next, %n879 br i1 %cond, label %loop, label %exit880 881exit: ; preds = %loop882 ret void883}884 885define void @fold_phi_non_add(i32 %init, i32 %n) {886; CHECK-LABEL: define void @fold_phi_non_add(887; CHECK-SAME: i32 [[INIT:%.*]], i32 [[N:%.*]]) {888; CHECK-NEXT: [[ENTRY:.*]]:889; CHECK-NEXT: [[TMP0:%.*]] = freeze i32 [[INIT]]890; CHECK-NEXT: br label %[[LOOP:.*]]891; CHECK: [[LOOP]]:892; CHECK-NEXT: [[I:%.*]] = phi i32 [ [[TMP0]], %[[ENTRY]] ], [ [[I_NEXT:%.*]], %[[LOOP]] ]893; CHECK-NEXT: [[I_NEXT]] = shl i32 [[I]], 1894; CHECK-NEXT: [[COND:%.*]] = icmp eq i32 [[I_NEXT]], [[N]]895; CHECK-NEXT: br i1 [[COND]], label %[[LOOP]], label %[[EXIT:.*]]896; CHECK: [[EXIT]]:897; CHECK-NEXT: ret void898;899entry:900 br label %loop901 902loop: ; preds = %loop, %entry903 %i = phi i32 [ %init, %entry ], [ %i.next, %loop ]904 %i.fr = freeze i32 %i905 %i.next = shl i32 %i.fr, 1906 %cond = icmp eq i32 %i.next, %n907 br i1 %cond, label %loop, label %exit908 909exit: ; preds = %loop910 ret void911}912 913define void @fold_phi_gep(ptr %init, ptr %end) {914; CHECK-LABEL: define void @fold_phi_gep(915; CHECK-SAME: ptr [[INIT:%.*]], ptr [[END:%.*]]) {916; CHECK-NEXT: [[ENTRY:.*]]:917; CHECK-NEXT: [[TMP0:%.*]] = freeze ptr [[INIT]]918; CHECK-NEXT: br label %[[LOOP:.*]]919; CHECK: [[LOOP]]:920; CHECK-NEXT: [[I:%.*]] = phi ptr [ [[TMP0]], %[[ENTRY]] ], [ [[I_NEXT:%.*]], %[[LOOP]] ]921; CHECK-NEXT: [[I_NEXT]] = getelementptr i8, ptr [[I]], i64 1922; CHECK-NEXT: [[COND:%.*]] = icmp eq ptr [[I_NEXT]], [[END]]923; CHECK-NEXT: br i1 [[COND]], label %[[LOOP]], label %[[EXIT:.*]]924; CHECK: [[EXIT]]:925; CHECK-NEXT: ret void926;927entry:928 br label %loop929 930loop: ; preds = %loop, %entry931 %i = phi ptr [ %init, %entry ], [ %i.next, %loop ]932 %i.fr = freeze ptr %i933 %i.next = getelementptr i8, ptr %i.fr, i64 1934 %cond = icmp eq ptr %i.next, %end935 br i1 %cond, label %loop, label %exit936 937exit: ; preds = %loop938 ret void939}940 941; The recurrence for the GEP offset can't produce poison so the freeze should942; be pushed through to the ptr.943define void @fold_phi_gep_phi_offset(ptr %init, ptr %end, i64 noundef %n) {944; CHECK-LABEL: define void @fold_phi_gep_phi_offset(945; CHECK-SAME: ptr [[INIT:%.*]], ptr [[END:%.*]], i64 noundef [[N:%.*]]) {946; CHECK-NEXT: [[ENTRY:.*]]:947; CHECK-NEXT: [[TMP0:%.*]] = freeze ptr [[INIT]]948; CHECK-NEXT: br label %[[LOOP:.*]]949; CHECK: [[LOOP]]:950; CHECK-NEXT: [[I:%.*]] = phi ptr [ [[TMP0]], %[[ENTRY]] ], [ [[I_NEXT:%.*]], %[[LOOP]] ]951; CHECK-NEXT: [[OFF:%.*]] = phi i64 [ [[N]], %[[ENTRY]] ], [ [[OFF_NEXT:%.*]], %[[LOOP]] ]952; CHECK-NEXT: [[OFF_NEXT]] = shl i64 [[OFF]], 3953; CHECK-NEXT: [[I_NEXT]] = getelementptr i8, ptr [[I]], i64 [[OFF_NEXT]]954; CHECK-NEXT: [[COND:%.*]] = icmp eq ptr [[I_NEXT]], [[END]]955; CHECK-NEXT: br i1 [[COND]], label %[[LOOP]], label %[[EXIT:.*]]956; CHECK: [[EXIT]]:957; CHECK-NEXT: ret void958;959entry:960 br label %loop961 962loop: ; preds = %loop, %entry963 %i = phi ptr [ %init, %entry ], [ %i.next.fr, %loop ]964 %off = phi i64 [ %n, %entry ], [ %off.next, %loop ]965 %off.next = shl i64 %off, 3966 %i.next = getelementptr i8, ptr %i, i64 %off.next967 %i.next.fr = freeze ptr %i.next968 %cond = icmp eq ptr %i.next.fr, %end969 br i1 %cond, label %loop, label %exit970 971exit: ; preds = %loop972 ret void973}974 975; Offset is still guaranteed not to be poison, so the freeze can be moved976; here if we strip inbounds from the GEP.977define void @fold_phi_gep_inbounds_phi_offset(ptr %init, ptr %end, i64 noundef %n) {978; CHECK-LABEL: define void @fold_phi_gep_inbounds_phi_offset(979; CHECK-SAME: ptr [[INIT:%.*]], ptr [[END:%.*]], i64 noundef [[N:%.*]]) {980; CHECK-NEXT: [[ENTRY:.*]]:981; CHECK-NEXT: [[TMP0:%.*]] = freeze ptr [[INIT]]982; CHECK-NEXT: br label %[[LOOP:.*]]983; CHECK: [[LOOP]]:984; CHECK-NEXT: [[I:%.*]] = phi ptr [ [[TMP0]], %[[ENTRY]] ], [ [[I_NEXT:%.*]], %[[LOOP]] ]985; CHECK-NEXT: [[OFF:%.*]] = phi i64 [ [[N]], %[[ENTRY]] ], [ [[OFF_NEXT:%.*]], %[[LOOP]] ]986; CHECK-NEXT: [[OFF_NEXT]] = shl i64 [[OFF]], 3987; CHECK-NEXT: [[I_NEXT]] = getelementptr i8, ptr [[I]], i64 [[OFF_NEXT]]988; CHECK-NEXT: [[COND:%.*]] = icmp eq ptr [[I_NEXT]], [[END]]989; CHECK-NEXT: br i1 [[COND]], label %[[LOOP]], label %[[EXIT:.*]]990; CHECK: [[EXIT]]:991; CHECK-NEXT: ret void992;993entry:994 br label %loop995 996loop: ; preds = %loop, %entry997 %i = phi ptr [ %init, %entry ], [ %i.next.fr, %loop ]998 %off = phi i64 [ %n, %entry ], [ %off.next, %loop ]999 %off.next = shl i64 %off, 31000 %i.next = getelementptr inbounds i8, ptr %i, i64 %off.next1001 %i.next.fr = freeze ptr %i.next1002 %cond = icmp eq ptr %i.next.fr, %end1003 br i1 %cond, label %loop, label %exit1004 1005exit: ; preds = %loop1006 ret void1007}1008 1009; Same as previous, but also requires freezing %n.1010define void @fold_phi_gep_phi_offset_multiple(ptr %init, ptr %end, i64 %n) {1011; CHECK-LABEL: define void @fold_phi_gep_phi_offset_multiple(1012; CHECK-SAME: ptr [[INIT:%.*]], ptr [[END:%.*]], i64 [[N:%.*]]) {1013; CHECK-NEXT: [[ENTRY:.*]]:1014; CHECK-NEXT: [[TMP0:%.*]] = freeze ptr [[INIT]]1015; CHECK-NEXT: [[TMP1:%.*]] = freeze i64 [[N]]1016; CHECK-NEXT: br label %[[LOOP:.*]]1017; CHECK: [[LOOP]]:1018; CHECK-NEXT: [[I:%.*]] = phi ptr [ [[TMP0]], %[[ENTRY]] ], [ [[I_NEXT:%.*]], %[[LOOP]] ]1019; CHECK-NEXT: [[OFF:%.*]] = phi i64 [ [[TMP1]], %[[ENTRY]] ], [ [[OFF_NEXT:%.*]], %[[LOOP]] ]1020; CHECK-NEXT: [[OFF_NEXT]] = shl i64 [[OFF]], 31021; CHECK-NEXT: [[I_NEXT]] = getelementptr i8, ptr [[I]], i64 [[OFF_NEXT]]1022; CHECK-NEXT: [[COND:%.*]] = icmp eq ptr [[I_NEXT]], [[END]]1023; CHECK-NEXT: br i1 [[COND]], label %[[LOOP]], label %[[EXIT:.*]]1024; CHECK: [[EXIT]]:1025; CHECK-NEXT: ret void1026;1027entry:1028 br label %loop1029 1030loop: ; preds = %loop, %entry1031 %i = phi ptr [ %init, %entry ], [ %i.next.fr, %loop ]1032 %off = phi i64 [ %n, %entry ], [ %off.next, %loop ]1033 %off.next = shl i64 %off, 31034 %i.next = getelementptr inbounds i8, ptr %i, i64 %off.next1035 %i.next.fr = freeze ptr %i.next1036 %cond = icmp eq ptr %i.next.fr, %end1037 br i1 %cond, label %loop, label %exit1038 1039exit: ; preds = %loop1040 ret void1041}1042 1043define void @fold_phi_multiple_insts(i32 %init, i32 %n) {1044; CHECK-LABEL: define void @fold_phi_multiple_insts(1045; CHECK-SAME: i32 [[INIT:%.*]], i32 [[N:%.*]]) {1046; CHECK-NEXT: [[ENTRY:.*]]:1047; CHECK-NEXT: [[INIT_FR:%.*]] = freeze i32 [[INIT]]1048; CHECK-NEXT: br label %[[LOOP:.*]]1049; CHECK: [[LOOP]]:1050; CHECK-NEXT: [[I:%.*]] = phi i32 [ [[INIT_FR]], %[[ENTRY]] ], [ [[I_NEXT:%.*]], %[[LOOP]] ]1051; CHECK-NEXT: [[I_SQ:%.*]] = mul i32 [[I]], [[I]]1052; CHECK-NEXT: [[I_NEXT]] = add i32 [[I_SQ]], 11053; CHECK-NEXT: [[COND:%.*]] = icmp eq i32 [[I_NEXT]], [[N]]1054; CHECK-NEXT: br i1 [[COND]], label %[[LOOP]], label %[[EXIT:.*]]1055; CHECK: [[EXIT]]:1056; CHECK-NEXT: ret void1057;1058entry:1059 br label %loop1060 1061loop: ; preds = %loop, %entry1062 %i = phi i32 [ %init, %entry ], [ %i.next, %loop ]1063 %i.fr = freeze i32 %i1064 %i.sq = mul nsw nuw i32 %i.fr, %i.fr1065 %i.next = add nsw nuw i32 %i.sq, 11066 %cond = icmp eq i32 %i.next, %n1067 br i1 %cond, label %loop, label %exit1068 1069exit: ; preds = %loop1070 ret void1071}1072 1073define void @fold_phi_multiple_back_edges(i32 %init, i32 %n, i32 %m) {1074; CHECK-LABEL: define void @fold_phi_multiple_back_edges(1075; CHECK-SAME: i32 [[INIT:%.*]], i32 [[N:%.*]], i32 [[M:%.*]]) {1076; CHECK-NEXT: [[ENTRY:.*]]:1077; CHECK-NEXT: [[INIT_FR:%.*]] = freeze i32 [[INIT]]1078; CHECK-NEXT: br label %[[LOOP:.*]]1079; CHECK: [[LOOP]]:1080; CHECK-NEXT: [[I:%.*]] = phi i32 [ [[INIT_FR]], %[[ENTRY]] ], [ [[I_NEXT:%.*]], %[[LOOP]] ], [ [[I_NEXT2:%.*]], %[[LOOP_LATCH2:.*]] ]1081; CHECK-NEXT: [[I_NEXT]] = add i32 [[I]], 11082; CHECK-NEXT: [[COND:%.*]] = icmp eq i32 [[I_NEXT]], [[N]]1083; CHECK-NEXT: br i1 [[COND]], label %[[LOOP]], label %[[LOOP_LATCH2]]1084; CHECK: [[LOOP_LATCH2]]:1085; CHECK-NEXT: [[I_NEXT2]] = add i32 [[I]], 21086; CHECK-NEXT: [[COND2:%.*]] = icmp eq i32 [[I_NEXT]], [[M]]1087; CHECK-NEXT: br i1 [[COND2]], label %[[LOOP]], label %[[EXIT:.*]]1088; CHECK: [[EXIT]]:1089; CHECK-NEXT: ret void1090;1091entry:1092 br label %loop1093 1094loop: ; preds = %loop, %entry1095 %i = phi i32 [ %init, %entry ], [ %i.next, %loop ], [ %i.next2, %loop.latch2 ]1096 %i.fr = freeze i32 %i1097 %i.next = add nsw nuw i32 %i.fr, 11098 %cond = icmp eq i32 %i.next, %n1099 br i1 %cond, label %loop, label %loop.latch21100 1101loop.latch2:1102 %i.next2 = add nsw nuw i32 %i.fr, 21103 %cond2 = icmp eq i32 %i.next, %m1104 br i1 %cond2, label %loop, label %exit1105 1106exit: ; preds = %loop1107 ret void1108}1109 1110define void @fold_phi_multiple_start_values(i1 %c, i32 %init, i32 %init2, i32 %n) {1111; CHECK-LABEL: define void @fold_phi_multiple_start_values(1112; CHECK-SAME: i1 [[C:%.*]], i32 [[INIT:%.*]], i32 [[INIT2:%.*]], i32 [[N:%.*]]) {1113; CHECK-NEXT: [[ENTRY:.*]]:1114; CHECK-NEXT: br i1 [[C]], label %[[IF:.*]], label %[[LOOP:.*]]1115; CHECK: [[IF]]:1116; CHECK-NEXT: br label %[[LOOP]]1117; CHECK: [[LOOP]]:1118; CHECK-NEXT: [[I:%.*]] = phi i32 [ [[INIT]], %[[ENTRY]] ], [ [[INIT2]], %[[IF]] ], [ [[I_NEXT:%.*]], %[[LOOP]] ]1119; CHECK-NEXT: [[I_FR:%.*]] = freeze i32 [[I]]1120; CHECK-NEXT: [[I_NEXT]] = add nuw nsw i32 [[I_FR]], 11121; CHECK-NEXT: [[COND:%.*]] = icmp eq i32 [[I_NEXT]], [[N]]1122; CHECK-NEXT: br i1 [[COND]], label %[[LOOP]], label %[[EXIT:.*]]1123; CHECK: [[EXIT]]:1124; CHECK-NEXT: ret void1125;1126entry:1127 br i1 %c, label %if, label %loop1128 1129if:1130 br label %loop1131 1132loop:1133 %i = phi i32 [ %init, %entry ], [ %init2, %if ], [ %i.next, %loop ]1134 %i.fr = freeze i32 %i1135 %i.next = add nsw nuw i32 %i.fr, 11136 %cond = icmp eq i32 %i.next, %n1137 br i1 %cond, label %loop, label %exit1138 1139exit:1140 ret void1141}1142 1143; We can remove this freeze as the incoming values to the PHI have the same1144; well-defined start value and the GEP can't produce poison, but this is1145; currently unsupported.1146define void @fold_phi_noundef_start_value(ptr noundef %init, i1 %cond.0, i1 %cond.1, i1 %cond.2) {1147; CHECK-LABEL: define void @fold_phi_noundef_start_value(1148; CHECK-SAME: ptr noundef [[INIT:%.*]], i1 [[COND_0:%.*]], i1 [[COND_1:%.*]], i1 [[COND_2:%.*]]) {1149; CHECK-NEXT: [[ENTRY:.*]]:1150; CHECK-NEXT: br label %[[LOOP:.*]]1151; CHECK: [[LOOP]]:1152; CHECK-NEXT: [[IV_0:%.*]] = phi ptr [ [[INIT]], %[[ENTRY]] ], [ [[IV_0_NEXT:%.*]], %[[LOOP_LATCH:.*]] ]1153; CHECK-NEXT: br i1 [[COND_0]], label %[[LOOP_LATCH]], label %[[IF_ELSE:.*]]1154; CHECK: [[IF_ELSE]]:1155; CHECK-NEXT: [[IV_1:%.*]] = getelementptr i8, ptr [[IV_0]], i64 -81156; CHECK-NEXT: br label %[[LOOP_LATCH]]1157; CHECK: [[LOOP_LATCH]]:1158; CHECK-NEXT: [[IV_2:%.*]] = phi ptr [ [[IV_0]], %[[LOOP]] ], [ [[IV_1]], %[[IF_ELSE]] ]1159; CHECK-NEXT: [[IV_2_FR:%.*]] = freeze ptr [[IV_2]]1160; CHECK-NEXT: [[IV_2_FR_INT:%.*]] = ptrtoint ptr [[IV_2_FR]] to i641161; CHECK-NEXT: [[IV_0_INT:%.*]] = ptrtoint ptr [[IV_0]] to i641162; CHECK-NEXT: [[IDX:%.*]] = sub i64 [[IV_0_INT]], [[IV_2_FR_INT]]1163; CHECK-NEXT: [[IV_0_NEXT]] = getelementptr i8, ptr [[IV_0]], i64 [[IDX]]1164; CHECK-NEXT: br i1 [[COND_2]], label %[[EXIT:.*]], label %[[LOOP]]1165; CHECK: [[EXIT]]:1166; CHECK-NEXT: ret void1167;1168entry:1169 br label %loop1170 1171loop:1172 %iv.0 = phi ptr [ %init, %entry ], [ %iv.0.next, %loop.latch ]1173 br i1 %cond.0, label %loop.latch, label %if.else1174 1175if.else:1176 %iv.1 = getelementptr i8, ptr %iv.0, i64 -81177 br label %loop.latch1178 1179loop.latch:1180 %iv.2 = phi ptr [ %iv.0, %loop ], [ %iv.1, %if.else ]1181 %iv.2.fr = freeze ptr %iv.21182 %iv.2.fr.int = ptrtoint ptr %iv.2.fr to i641183 %iv.0.int = ptrtoint ptr %iv.0 to i641184 %idx = sub i64 %iv.0.int, %iv.2.fr.int1185 %iv.0.next = getelementptr i8, ptr %iv.0, i64 %idx1186 br i1 %cond.2, label %exit, label %loop1187 1188exit:1189 ret void1190}1191 1192define void @fold_phi_invoke_start_value(i32 %n) personality ptr undef {1193; CHECK-LABEL: define void @fold_phi_invoke_start_value(1194; CHECK-SAME: i32 [[N:%.*]]) personality ptr undef {1195; CHECK-NEXT: [[ENTRY:.*]]:1196; CHECK-NEXT: [[INIT:%.*]] = invoke i32 @get_i32()1197; CHECK-NEXT: to label %[[LOOP:.*]] unwind label %[[UNWIND:.*]]1198; CHECK: [[LOOP]]:1199; CHECK-NEXT: [[I:%.*]] = phi i32 [ [[INIT]], %[[ENTRY]] ], [ [[I_NEXT:%.*]], %[[LOOP]] ]1200; CHECK-NEXT: [[I_FR:%.*]] = freeze i32 [[I]]1201; CHECK-NEXT: [[I_NEXT]] = add nuw nsw i32 [[I_FR]], 11202; CHECK-NEXT: [[COND:%.*]] = icmp eq i32 [[I_NEXT]], [[N]]1203; CHECK-NEXT: br i1 [[COND]], label %[[LOOP]], label %[[EXIT:.*]]1204; CHECK: [[UNWIND]]:1205; CHECK-NEXT: [[TMP0:%.*]] = landingpad i81206; CHECK-NEXT: cleanup1207; CHECK-NEXT: unreachable1208; CHECK: [[EXIT]]:1209; CHECK-NEXT: ret void1210;1211entry:1212 %init = invoke i32 @get_i32()1213 to label %loop unwind label %unwind1214 1215loop:1216 %i = phi i32 [ %init, %entry ], [ %i.next, %loop ]1217 %i.fr = freeze i32 %i1218 %i.next = add nsw nuw i32 %i.fr, 11219 %cond = icmp eq i32 %i.next, %n1220 br i1 %cond, label %loop, label %exit1221 1222unwind:1223 landingpad i8 cleanup1224 unreachable1225 1226exit:1227 ret void1228}1229 1230define void @fold_phi_invoke_noundef_start_value(i32 %n) personality ptr undef {1231; CHECK-LABEL: define void @fold_phi_invoke_noundef_start_value(1232; CHECK-SAME: i32 [[N:%.*]]) personality ptr undef {1233; CHECK-NEXT: [[ENTRY:.*]]:1234; CHECK-NEXT: [[INIT:%.*]] = invoke noundef i32 @get_i32()1235; CHECK-NEXT: to label %[[LOOP:.*]] unwind label %[[UNWIND:.*]]1236; CHECK: [[LOOP]]:1237; CHECK-NEXT: [[I:%.*]] = phi i32 [ [[INIT]], %[[ENTRY]] ], [ [[I_NEXT:%.*]], %[[LOOP]] ]1238; CHECK-NEXT: [[I_NEXT]] = add i32 [[I]], 11239; CHECK-NEXT: [[COND:%.*]] = icmp eq i32 [[I_NEXT]], [[N]]1240; CHECK-NEXT: br i1 [[COND]], label %[[LOOP]], label %[[EXIT:.*]]1241; CHECK: [[UNWIND]]:1242; CHECK-NEXT: [[TMP0:%.*]] = landingpad i81243; CHECK-NEXT: cleanup1244; CHECK-NEXT: unreachable1245; CHECK: [[EXIT]]:1246; CHECK-NEXT: ret void1247;1248entry:1249 %init = invoke noundef i32 @get_i32()1250 to label %loop unwind label %unwind1251 1252loop:1253 %i = phi i32 [ %init, %entry ], [ %i.next, %loop ]1254 %i.fr = freeze i32 %i1255 %i.next = add nsw nuw i32 %i.fr, 11256 %cond = icmp eq i32 %i.next, %n1257 br i1 %cond, label %loop, label %exit1258 1259unwind:1260 landingpad i8 cleanup1261 unreachable1262 1263exit:1264 ret void1265}1266 1267define ptr @freeze_load_noundef(ptr %ptr) {1268; CHECK-LABEL: define ptr @freeze_load_noundef(1269; CHECK-SAME: ptr [[PTR:%.*]]) {1270; CHECK-NEXT: [[P:%.*]] = load ptr, ptr [[PTR]], align 8, !noundef [[META0:![0-9]+]]1271; CHECK-NEXT: ret ptr [[P]]1272;1273 %p = load ptr, ptr %ptr, !noundef !01274 %p.fr = freeze ptr %p1275 ret ptr %p.fr1276}1277 1278define ptr @freeze_load_dereferenceable(ptr %ptr) {1279; CHECK-LABEL: define ptr @freeze_load_dereferenceable(1280; CHECK-SAME: ptr [[PTR:%.*]]) {1281; CHECK-NEXT: [[P:%.*]] = load ptr, ptr [[PTR]], align 8, !dereferenceable [[META1:![0-9]+]]1282; CHECK-NEXT: ret ptr [[P]]1283;1284 %p = load ptr, ptr %ptr, !dereferenceable !11285 %p.fr = freeze ptr %p1286 ret ptr %p.fr1287}1288 1289define ptr @freeze_load_dereferenceable_or_null(ptr %ptr) {1290; CHECK-LABEL: define ptr @freeze_load_dereferenceable_or_null(1291; CHECK-SAME: ptr [[PTR:%.*]]) {1292; CHECK-NEXT: [[P:%.*]] = load ptr, ptr [[PTR]], align 8, !dereferenceable_or_null [[META1]]1293; CHECK-NEXT: ret ptr [[P]]1294;1295 %p = load ptr, ptr %ptr, !dereferenceable_or_null !11296 %p.fr = freeze ptr %p1297 ret ptr %p.fr1298}1299 1300define i32 @freeze_load_with_range(ptr %ptr) {1301; CHECK-LABEL: define i32 @freeze_load_with_range(1302; CHECK-SAME: ptr [[PTR:%.*]]) {1303; CHECK-NEXT: [[X:%.*]] = load i32, ptr [[PTR]], align 4, !range [[RNG2:![0-9]+]]1304; CHECK-NEXT: [[X_FR:%.*]] = freeze i32 [[X]]1305; CHECK-NEXT: ret i32 [[X_FR]]1306;1307 %x = load i32, ptr %ptr, !range !21308 %x.fr = freeze i32 %x1309 ret i32 %x.fr1310}1311 1312declare i32 @foo.i32()1313 1314define i32 @freeze_call_with_range() {1315; CHECK-LABEL: define i32 @freeze_call_with_range() {1316; CHECK-NEXT: [[X:%.*]] = call i32 @foo.i32(), !range [[RNG2]]1317; CHECK-NEXT: [[X_FR:%.*]] = freeze i32 [[X]]1318; CHECK-NEXT: ret i32 [[X_FR]]1319;1320 %x = call i32 @foo.i32(), !range !21321 %x.fr = freeze i32 %x1322 ret i32 %x.fr1323}1324 1325declare i32 @llvm.ctpop.i32(i32)1326 1327define i32 @freeze_ctpop(i32 %x) {1328; CHECK-LABEL: define i32 @freeze_ctpop(1329; CHECK-SAME: i32 [[X:%.*]]) {1330; CHECK-NEXT: [[Y:%.*]] = lshr i32 2047, [[X]]1331; CHECK-NEXT: [[Y_FR:%.*]] = freeze i32 [[Y]]1332; CHECK-NEXT: [[CTPOP:%.*]] = call range(i32 0, 33) i32 @llvm.ctpop.i32(i32 [[Y_FR]])1333; CHECK-NEXT: ret i32 [[CTPOP]]1334;1335 %y = lshr i32 2047, %x1336 %ctpop = call i32 @llvm.ctpop.i32(i32 %y)1337 %fr = freeze i32 %ctpop1338 ret i32 %fr1339}1340 1341define i32 @freeze_zext_nneg(i8 %x) {1342; CHECK-LABEL: define i32 @freeze_zext_nneg(1343; CHECK-SAME: i8 [[X:%.*]]) {1344; CHECK-NEXT: [[X_FR:%.*]] = freeze i8 [[X]]1345; CHECK-NEXT: [[ZEXT:%.*]] = zext i8 [[X_FR]] to i321346; CHECK-NEXT: ret i32 [[ZEXT]]1347;1348 %zext = zext nneg i8 %x to i321349 %fr = freeze i32 %zext1350 ret i32 %fr1351}1352 1353define float @freeze_uitofp_nneg(i8 %x) {1354; CHECK-LABEL: define float @freeze_uitofp_nneg(1355; CHECK-SAME: i8 [[X:%.*]]) {1356; CHECK-NEXT: [[X_FR:%.*]] = freeze i8 [[X]]1357; CHECK-NEXT: [[UITOFP:%.*]] = uitofp i8 [[X_FR]] to float1358; CHECK-NEXT: ret float [[UITOFP]]1359;1360 %uitofp = uitofp nneg i8 %x to float1361 %fr = freeze float %uitofp1362 ret float %fr1363}1364 1365define i32 @propagate_drop_flags_or(i32 %arg) {1366; CHECK-LABEL: define i32 @propagate_drop_flags_or(1367; CHECK-SAME: i32 [[ARG:%.*]]) {1368; CHECK-NEXT: [[ARG_FR:%.*]] = freeze i32 [[ARG]]1369; CHECK-NEXT: [[V1:%.*]] = or i32 [[ARG_FR]], 21370; CHECK-NEXT: ret i32 [[V1]]1371;1372 %v1 = or disjoint i32 %arg, 21373 %v1.fr = freeze i32 %v11374 ret i32 %v1.fr1375}1376 1377define i32 @propagate_drop_flags_trunc(i64 %arg) {1378; CHECK-LABEL: define i32 @propagate_drop_flags_trunc(1379; CHECK-SAME: i64 [[ARG:%.*]]) {1380; CHECK-NEXT: [[ARG_FR:%.*]] = freeze i64 [[ARG]]1381; CHECK-NEXT: [[V1:%.*]] = trunc i64 [[ARG_FR]] to i321382; CHECK-NEXT: ret i32 [[V1]]1383;1384 %v1 = trunc nsw nuw i64 %arg to i321385 %v1.fr = freeze i32 %v11386 ret i32 %v1.fr1387}1388 1389define ptr @propagate_drop_flags_gep_nusw(ptr %p) {1390; CHECK-LABEL: define ptr @propagate_drop_flags_gep_nusw(1391; CHECK-SAME: ptr [[P:%.*]]) {1392; CHECK-NEXT: [[P_FR:%.*]] = freeze ptr [[P]]1393; CHECK-NEXT: [[GEP:%.*]] = getelementptr i8, ptr [[P_FR]], i64 11394; CHECK-NEXT: ret ptr [[GEP]]1395;1396 %gep = getelementptr nusw i8, ptr %p, i64 11397 %gep.fr = freeze ptr %gep1398 ret ptr %gep.fr1399}1400 1401define ptr @propagate_drop_flags_gep_nuw(ptr %p) {1402; CHECK-LABEL: define ptr @propagate_drop_flags_gep_nuw(1403; CHECK-SAME: ptr [[P:%.*]]) {1404; CHECK-NEXT: [[P_FR:%.*]] = freeze ptr [[P]]1405; CHECK-NEXT: [[GEP:%.*]] = getelementptr i8, ptr [[P_FR]], i64 11406; CHECK-NEXT: ret ptr [[GEP]]1407;1408 %gep = getelementptr nuw i8, ptr %p, i64 11409 %gep.fr = freeze ptr %gep1410 ret ptr %gep.fr1411}1412 1413define i1 @propagate_drop_flags_icmp(i32 %a, i32 %b) {1414; CHECK-LABEL: define i1 @propagate_drop_flags_icmp(1415; CHECK-SAME: i32 [[A:%.*]], i32 [[B:%.*]]) {1416; CHECK-NEXT: [[A_FR:%.*]] = freeze i32 [[A]]1417; CHECK-NEXT: [[RET:%.*]] = icmp ult i32 [[A_FR]], 31418; CHECK-NEXT: ret i1 [[RET]]1419;1420 %ret = icmp samesign ult i32 %a, 31421 %ret.fr = freeze i1 %ret1422 ret i1 %ret.fr1423}1424 1425declare i32 @llvm.umax.i32(i32 %a, i32 %b)1426 1427define i32 @freeze_call_with_range_attr(i32 %a) {1428; CHECK-LABEL: define i32 @freeze_call_with_range_attr(1429; CHECK-SAME: i32 [[A:%.*]]) {1430; CHECK-NEXT: [[Y:%.*]] = lshr i32 2047, [[A]]1431; CHECK-NEXT: [[Y_FR:%.*]] = freeze i32 [[Y]]1432; CHECK-NEXT: [[X:%.*]] = call i32 @llvm.umax.i32(i32 [[Y_FR]], i32 50)1433; CHECK-NEXT: ret i32 [[X]]1434;1435 %y = lshr i32 2047, %a1436 %x = call range(i32 0, 2048) i32 @llvm.umax.i32(i32 %y, i32 50)1437 %x.fr = freeze i32 %x1438 ret i32 %x.fr1439}1440 1441declare ptr @llvm.ptrmask.p0.i64(ptr, i64)1442 1443define ptr @freeze_ptrmask_align(ptr %p, i64 noundef %m) {1444; CHECK-LABEL: define ptr @freeze_ptrmask_align(1445; CHECK-SAME: ptr [[P:%.*]], i64 noundef [[M:%.*]]) {1446; CHECK-NEXT: [[P_FR:%.*]] = freeze ptr [[P]]1447; CHECK-NEXT: [[MASK:%.*]] = call ptr @llvm.ptrmask.p0.i64(ptr [[P_FR]], i64 [[M]])1448; CHECK-NEXT: ret ptr [[MASK]]1449;1450 %mask = call align(4) ptr @llvm.ptrmask.p0.i64(ptr %p, i64 %m)1451 %fr = freeze ptr %mask1452 ret ptr %fr1453}1454 1455define ptr @freeze_ptrmask_nonnull(ptr %p, i64 noundef %m) {1456; CHECK-LABEL: define ptr @freeze_ptrmask_nonnull(1457; CHECK-SAME: ptr [[P:%.*]], i64 noundef [[M:%.*]]) {1458; CHECK-NEXT: [[P_FR:%.*]] = freeze ptr [[P]]1459; CHECK-NEXT: [[MASK:%.*]] = call ptr @llvm.ptrmask.p0.i64(ptr [[P_FR]], i64 [[M]])1460; CHECK-NEXT: ret ptr [[MASK]]1461;1462 %mask = call nonnull ptr @llvm.ptrmask.p0.i64(ptr %p, i64 %m)1463 %fr = freeze ptr %mask1464 ret ptr %fr1465}1466 1467define i64 @pr161492_1(i1 %cond) {1468; CHECK-LABEL: define i64 @pr161492_1(1469; CHECK-SAME: i1 [[COND:%.*]]) {1470; CHECK-NEXT: ret i64 01471;1472 %fr1 = freeze i64 poison1473 %fr2 = freeze i64 poison1474 %ret = select i1 %cond, i64 %fr1, i64 %fr21475 ret i64 %ret1476}1477 1478define i64 @pr161492_2(i1 %cond) {1479; CHECK-LABEL: define i64 @pr161492_2(1480; CHECK-SAME: i1 [[COND:%.*]]) {1481; CHECK-NEXT: ret i64 01482;1483 %fr = freeze i64 poison1484 %ret = select i1 %cond, i64 %fr, i64 %fr1485 ret i64 %ret1486}1487 1488!0 = !{}1489!1 = !{i64 4}1490!2 = !{i32 0, i32 100}1491;.1492; CHECK: [[META0]] = !{}1493; CHECK: [[META1]] = !{i64 4}1494; CHECK: [[RNG2]] = !{i32 0, i32 100}1495;.1496