brintos

brintos / llvm-project-archived public Read only

0
0
Text · 47.6 KiB · ac7d65c Raw
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