1391 lines · plain
1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --function-signature --check-attributes --check-globals2; RUN: opt -aa-pipeline=basic-aa -passes=attributor -attributor-manifest-internal -attributor-annotate-decl-cs -S < %s | FileCheck %s --check-prefixes=CHECK,TUNIT3; RUN: opt -aa-pipeline=basic-aa -passes=attributor-cgscc -attributor-manifest-internal -attributor-annotate-decl-cs -S < %s | FileCheck %s --check-prefixes=CHECK,CGSCC4 5@Gstatic_int1 = internal global i32 zeroinitializer, align 46@Gstatic_int2 = internal global i32 zeroinitializer, align 47 8declare void @llvm.assume(i1)9declare void @useI1p(ptr)10declare void @unknown()11 12;.13; CHECK: @Gstatic_int1 = internal global i32 0, align 414; CHECK: @Gstatic_int2 = internal global i32 0, align 415;.16define i1 @readI1p(ptr %p) {17; CHECK: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(argmem: read)18; CHECK-LABEL: define {{[^@]+}}@readI1p19; CHECK-SAME: (ptr nofree noundef nonnull readonly captures(none) dereferenceable(1) [[P:%.*]]) #[[ATTR1:[0-9]+]] {20; CHECK-NEXT: [[L:%.*]] = load i1, ptr [[P]], align 121; CHECK-NEXT: ret i1 [[L]]22;23 %l = load i1, ptr %p24 ret i1 %l25}26 27define i1 @keep_assume_1c_nr() norecurse {28; CHECK: Function Attrs: norecurse29; CHECK-LABEL: define {{[^@]+}}@keep_assume_1c_nr30; CHECK-SAME: () #[[ATTR2:[0-9]+]] {31; CHECK-NEXT: [[STACK:%.*]] = alloca i1, align 132; CHECK-NEXT: store i1 true, ptr [[STACK]], align 133; CHECK-NEXT: call void @useI1p(ptr noundef nonnull dereferenceable(1) [[STACK]])34; CHECK-NEXT: [[L:%.*]] = load i1, ptr [[STACK]], align 135; CHECK-NEXT: call void @llvm.assume(i1 noundef [[L]])36; CHECK-NEXT: ret i1 [[L]]37;38 %stack = alloca i139 store i1 true, ptr %stack40 call void @useI1p(ptr %stack)41 %l = load i1, ptr %stack42 call void @llvm.assume(i1 %l)43 ret i1 %l44}45 46define i1 @drop_assume_1c_nr() norecurse {47; TUNIT: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(inaccessiblemem: write)48; TUNIT-LABEL: define {{[^@]+}}@drop_assume_1c_nr49; TUNIT-SAME: () #[[ATTR3:[0-9]+]] {50; TUNIT-NEXT: call void @llvm.assume(i1 noundef true) #[[ATTR7:[0-9]+]]51; TUNIT-NEXT: ret i1 true52;53; CGSCC: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(inaccessiblemem: write)54; CGSCC-LABEL: define {{[^@]+}}@drop_assume_1c_nr55; CGSCC-SAME: () #[[ATTR3:[0-9]+]] {56; CGSCC-NEXT: call void @llvm.assume(i1 noundef true) #[[ATTR8:[0-9]+]]57; CGSCC-NEXT: ret i1 true58;59 %stack = alloca i160 store i1 true, ptr %stack61 %l = load i1, ptr %stack62 call void @llvm.assume(i1 %l)63 ret i1 %l64}65 66define i1 @keep_assume_2c_nr() norecurse {67; CHECK: Function Attrs: norecurse68; CHECK-LABEL: define {{[^@]+}}@keep_assume_2c_nr69; CHECK-SAME: () #[[ATTR2]] {70; CHECK-NEXT: [[STACK:%.*]] = alloca i1, align 171; CHECK-NEXT: store i1 true, ptr [[STACK]], align 172; CHECK-NEXT: call void @useI1p(ptr noundef nonnull dereferenceable(1) [[STACK]])73; CHECK-NEXT: [[L1:%.*]] = load i1, ptr [[STACK]], align 174; CHECK-NEXT: call void @llvm.assume(i1 noundef [[L1]])75; CHECK-NEXT: call void @unknown()76; CHECK-NEXT: [[L2:%.*]] = load i1, ptr [[STACK]], align 177; CHECK-NEXT: ret i1 [[L2]]78;79 %stack = alloca i180 store i1 true, ptr %stack81 call void @useI1p(ptr %stack)82 %l1 = load i1, ptr %stack83 call void @llvm.assume(i1 %l1)84 call void @unknown()85 %l2 = load i1, ptr %stack86 ret i1 %l287}88 89define i1 @keep_assume_3c_nr() norecurse {90;91; TUNIT: Function Attrs: norecurse92; TUNIT-LABEL: define {{[^@]+}}@keep_assume_3c_nr93; TUNIT-SAME: () #[[ATTR2]] {94; TUNIT-NEXT: [[STACK:%.*]] = alloca i1, align 195; TUNIT-NEXT: store i1 true, ptr [[STACK]], align 196; TUNIT-NEXT: [[L:%.*]] = load i1, ptr [[STACK]], align 197; TUNIT-NEXT: call void @llvm.assume(i1 noundef [[L]]) #[[ATTR7]]98; TUNIT-NEXT: call void @useI1p(ptr noundef nonnull dereferenceable(1) [[STACK]])99; TUNIT-NEXT: ret i1 [[L]]100;101; CGSCC: Function Attrs: norecurse102; CGSCC-LABEL: define {{[^@]+}}@keep_assume_3c_nr103; CGSCC-SAME: () #[[ATTR2]] {104; CGSCC-NEXT: [[STACK:%.*]] = alloca i1, align 1105; CGSCC-NEXT: store i1 true, ptr [[STACK]], align 1106; CGSCC-NEXT: [[L:%.*]] = load i1, ptr [[STACK]], align 1107; CGSCC-NEXT: call void @llvm.assume(i1 noundef [[L]]) #[[ATTR8]]108; CGSCC-NEXT: call void @useI1p(ptr noundef nonnull dereferenceable(1) [[STACK]])109; CGSCC-NEXT: ret i1 [[L]]110;111 %stack = alloca i1112 store i1 true, ptr %stack113 %l = load i1, ptr %stack114 call void @llvm.assume(i1 %l)115 call void @useI1p(ptr %stack)116 ret i1 %l117}118define i1 @keep_assume_4c_nr() norecurse {119;120; TUNIT: Function Attrs: norecurse121; TUNIT-LABEL: define {{[^@]+}}@keep_assume_4c_nr122; TUNIT-SAME: () #[[ATTR2]] {123; TUNIT-NEXT: [[STACK:%.*]] = alloca i1, align 1124; TUNIT-NEXT: store i1 true, ptr [[STACK]], align 1125; TUNIT-NEXT: call void @llvm.assume(i1 noundef true) #[[ATTR7]]126; TUNIT-NEXT: call void @useI1p(ptr noalias noundef nonnull captures(none) dereferenceable(1) [[STACK]])127; TUNIT-NEXT: ret i1 true128;129; CGSCC: Function Attrs: norecurse130; CGSCC-LABEL: define {{[^@]+}}@keep_assume_4c_nr131; CGSCC-SAME: () #[[ATTR2]] {132; CGSCC-NEXT: [[STACK:%.*]] = alloca i1, align 1133; CGSCC-NEXT: store i1 true, ptr [[STACK]], align 1134; CGSCC-NEXT: call void @llvm.assume(i1 noundef true) #[[ATTR8]]135; CGSCC-NEXT: call void @useI1p(ptr noalias noundef nonnull captures(none) dereferenceable(1) [[STACK]])136; CGSCC-NEXT: ret i1 true137;138 %stack = alloca i1139 store i1 true, ptr %stack140 %l4 = load i1, ptr %stack141 call void @llvm.assume(i1 %l4)142 call void @useI1p(ptr nocapture %stack)143 ret i1 %l4144}145 146define i1 @keep_assume_1_nr(i1 %arg) norecurse {147; CHECK: Function Attrs: norecurse148; CHECK-LABEL: define {{[^@]+}}@keep_assume_1_nr149; CHECK-SAME: (i1 [[ARG:%.*]]) #[[ATTR2]] {150; CHECK-NEXT: [[STACK:%.*]] = alloca i1, align 1151; CHECK-NEXT: store i1 [[ARG]], ptr [[STACK]], align 1152; CHECK-NEXT: call void @useI1p(ptr noundef nonnull dereferenceable(1) [[STACK]])153; CHECK-NEXT: [[L:%.*]] = load i1, ptr [[STACK]], align 1154; CHECK-NEXT: call void @llvm.assume(i1 noundef [[L]])155; CHECK-NEXT: ret i1 [[L]]156;157 %stack = alloca i1158 store i1 %arg, ptr %stack159 call void @useI1p(ptr %stack)160 %l = load i1, ptr %stack161 call void @llvm.assume(i1 %l)162 ret i1 %l163}164 165define i1 @drop_assume_1_nr(i1 %arg) norecurse {166; TUNIT: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(inaccessiblemem: readwrite)167; TUNIT-LABEL: define {{[^@]+}}@drop_assume_1_nr168; TUNIT-SAME: (i1 returned [[ARG:%.*]]) #[[ATTR4:[0-9]+]] {169; TUNIT-NEXT: [[STACK:%.*]] = alloca i1, align 1170; TUNIT-NEXT: store i1 [[ARG]], ptr [[STACK]], align 1171; TUNIT-NEXT: call void @llvm.assume(i1 noundef [[ARG]]) #[[ATTR7]]172; TUNIT-NEXT: ret i1 [[ARG]]173;174; CGSCC: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(inaccessiblemem: readwrite)175; CGSCC-LABEL: define {{[^@]+}}@drop_assume_1_nr176; CGSCC-SAME: (i1 returned [[ARG:%.*]]) #[[ATTR4:[0-9]+]] {177; CGSCC-NEXT: [[STACK:%.*]] = alloca i1, align 1178; CGSCC-NEXT: store i1 [[ARG]], ptr [[STACK]], align 1179; CGSCC-NEXT: call void @llvm.assume(i1 noundef [[ARG]]) #[[ATTR8]]180; CGSCC-NEXT: ret i1 [[ARG]]181;182 %stack = alloca i1183 store i1 %arg, ptr %stack184 %l = load i1, ptr %stack185 call void @llvm.assume(i1 %l)186 ret i1 %l187}188 189define i1 @keep_assume_2_nr(i1 %arg) norecurse {190; CHECK: Function Attrs: norecurse191; CHECK-LABEL: define {{[^@]+}}@keep_assume_2_nr192; CHECK-SAME: (i1 [[ARG:%.*]]) #[[ATTR2]] {193; CHECK-NEXT: [[STACK:%.*]] = alloca i1, align 1194; CHECK-NEXT: store i1 [[ARG]], ptr [[STACK]], align 1195; CHECK-NEXT: call void @useI1p(ptr noundef nonnull dereferenceable(1) [[STACK]])196; CHECK-NEXT: [[L1:%.*]] = load i1, ptr [[STACK]], align 1197; CHECK-NEXT: call void @llvm.assume(i1 noundef [[L1]])198; CHECK-NEXT: call void @unknown()199; CHECK-NEXT: [[L2:%.*]] = load i1, ptr [[STACK]], align 1200; CHECK-NEXT: ret i1 [[L2]]201;202 %stack = alloca i1203 store i1 %arg, ptr %stack204 call void @useI1p(ptr %stack)205 %l1 = load i1, ptr %stack206 call void @llvm.assume(i1 %l1)207 call void @unknown()208 %l2 = load i1, ptr %stack209 ret i1 %l2210}211 212define i1 @keep_assume_3_nr(i1 %arg) norecurse {213;214; TUNIT: Function Attrs: norecurse215; TUNIT-LABEL: define {{[^@]+}}@keep_assume_3_nr216; TUNIT-SAME: (i1 [[ARG:%.*]]) #[[ATTR2]] {217; TUNIT-NEXT: [[STACK:%.*]] = alloca i1, align 1218; TUNIT-NEXT: store i1 [[ARG]], ptr [[STACK]], align 1219; TUNIT-NEXT: [[L:%.*]] = load i1, ptr [[STACK]], align 1220; TUNIT-NEXT: call void @llvm.assume(i1 noundef [[L]]) #[[ATTR7]]221; TUNIT-NEXT: call void @useI1p(ptr noundef nonnull dereferenceable(1) [[STACK]])222; TUNIT-NEXT: ret i1 [[L]]223;224; CGSCC: Function Attrs: norecurse225; CGSCC-LABEL: define {{[^@]+}}@keep_assume_3_nr226; CGSCC-SAME: (i1 [[ARG:%.*]]) #[[ATTR2]] {227; CGSCC-NEXT: [[STACK:%.*]] = alloca i1, align 1228; CGSCC-NEXT: store i1 [[ARG]], ptr [[STACK]], align 1229; CGSCC-NEXT: [[L:%.*]] = load i1, ptr [[STACK]], align 1230; CGSCC-NEXT: call void @llvm.assume(i1 noundef [[L]]) #[[ATTR8]]231; CGSCC-NEXT: call void @useI1p(ptr noundef nonnull dereferenceable(1) [[STACK]])232; CGSCC-NEXT: ret i1 [[L]]233;234 %stack = alloca i1235 store i1 %arg, ptr %stack236 %l = load i1, ptr %stack237 call void @llvm.assume(i1 %l)238 call void @useI1p(ptr %stack)239 ret i1 %l240}241 242define i1 @keep_assume_4_nr(i1 %arg) norecurse {243;244; TUNIT: Function Attrs: norecurse245; TUNIT-LABEL: define {{[^@]+}}@keep_assume_4_nr246; TUNIT-SAME: (i1 returned [[ARG:%.*]]) #[[ATTR2]] {247; TUNIT-NEXT: [[STACK:%.*]] = alloca i1, align 1248; TUNIT-NEXT: store i1 [[ARG]], ptr [[STACK]], align 1249; TUNIT-NEXT: call void @llvm.assume(i1 noundef [[ARG]]) #[[ATTR7]]250; TUNIT-NEXT: call void @useI1p(ptr noalias noundef nonnull captures(none) dereferenceable(1) [[STACK]])251; TUNIT-NEXT: ret i1 [[ARG]]252;253; CGSCC: Function Attrs: norecurse254; CGSCC-LABEL: define {{[^@]+}}@keep_assume_4_nr255; CGSCC-SAME: (i1 returned [[ARG:%.*]]) #[[ATTR2]] {256; CGSCC-NEXT: [[STACK:%.*]] = alloca i1, align 1257; CGSCC-NEXT: store i1 [[ARG]], ptr [[STACK]], align 1258; CGSCC-NEXT: call void @llvm.assume(i1 noundef [[ARG]]) #[[ATTR8]]259; CGSCC-NEXT: call void @useI1p(ptr noalias noundef nonnull captures(none) dereferenceable(1) [[STACK]])260; CGSCC-NEXT: ret i1 [[ARG]]261;262 %stack = alloca i1263 store i1 %arg, ptr %stack264 %l = load i1, ptr %stack265 call void @llvm.assume(i1 %l)266 call void @useI1p(ptr nocapture %stack)267 ret i1 %l268}269 270define i1 @assume_1_nr(i1 %arg, i1 %cond) norecurse {271; TUNIT: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(inaccessiblemem: readwrite)272; TUNIT-LABEL: define {{[^@]+}}@assume_1_nr273; TUNIT-SAME: (i1 returned [[ARG:%.*]], i1 noundef [[COND:%.*]]) #[[ATTR4]] {274; TUNIT-NEXT: [[STACK:%.*]] = alloca i1, align 1275; TUNIT-NEXT: store i1 [[ARG]], ptr [[STACK]], align 1276; TUNIT-NEXT: call void @llvm.assume(i1 noundef [[ARG]]) #[[ATTR7]]277; TUNIT-NEXT: br i1 [[COND]], label [[T:%.*]], label [[F:%.*]]278; TUNIT: t:279; TUNIT-NEXT: br label [[M:%.*]]280; TUNIT: f:281; TUNIT-NEXT: br label [[M]]282; TUNIT: m:283; TUNIT-NEXT: ret i1 [[ARG]]284;285; CGSCC: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(inaccessiblemem: readwrite)286; CGSCC-LABEL: define {{[^@]+}}@assume_1_nr287; CGSCC-SAME: (i1 returned [[ARG:%.*]], i1 noundef [[COND:%.*]]) #[[ATTR4]] {288; CGSCC-NEXT: [[STACK:%.*]] = alloca i1, align 1289; CGSCC-NEXT: store i1 [[ARG]], ptr [[STACK]], align 1290; CGSCC-NEXT: call void @llvm.assume(i1 noundef [[ARG]]) #[[ATTR8]]291; CGSCC-NEXT: br i1 [[COND]], label [[T:%.*]], label [[F:%.*]]292; CGSCC: t:293; CGSCC-NEXT: br label [[M:%.*]]294; CGSCC: f:295; CGSCC-NEXT: br label [[M]]296; CGSCC: m:297; CGSCC-NEXT: ret i1 [[ARG]]298;299 %stack = alloca i1300 store i1 %arg, ptr %stack301 %l = load i1, ptr %stack302 call void @llvm.assume(i1 %l)303 br i1 %cond, label %t, label %f304t:305 store i1 true, ptr %stack306 br label %m307f:308 store i1 false, ptr %stack309 br label %m310m:311 ret i1 %l312}313 314define void @assume_1b_nr(i1 %arg, i1 %cond) norecurse {315; CHECK: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(inaccessiblemem: readwrite)316; CHECK-LABEL: define {{[^@]+}}@assume_1b_nr317; CHECK-SAME: (i1 [[ARG:%.*]], i1 noundef [[COND:%.*]]) #[[ATTR4:[0-9]+]] {318; CHECK-NEXT: br i1 [[COND]], label [[T:%.*]], label [[F:%.*]]319; CHECK: t:320; CHECK-NEXT: br label [[M:%.*]]321; CHECK: f:322; CHECK-NEXT: br label [[M]]323; CHECK: m:324; CHECK-NEXT: ret void325;326 %stack = alloca i1327 store i1 %arg, ptr %stack328 %l = load i1, ptr %stack329 call void @llvm.assume(i1 %l)330 br i1 %cond, label %t, label %f331t:332 store i1 true, ptr %stack333 br label %m334f:335 store i1 false, ptr %stack336 br label %m337m:338 ret void339}340 341define i1 @assume_2_nr(i1 %arg, i1 %cond) norecurse {342; TUNIT: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(inaccessiblemem: readwrite)343; TUNIT-LABEL: define {{[^@]+}}@assume_2_nr344; TUNIT-SAME: (i1 [[ARG:%.*]], i1 noundef [[COND:%.*]]) #[[ATTR4]] {345; TUNIT-NEXT: [[STACK:%.*]] = alloca i1, align 1346; TUNIT-NEXT: br i1 [[COND]], label [[T:%.*]], label [[F:%.*]]347; TUNIT: t:348; TUNIT-NEXT: store i1 true, ptr [[STACK]], align 1349; TUNIT-NEXT: br label [[M:%.*]]350; TUNIT: f:351; TUNIT-NEXT: store i1 false, ptr [[STACK]], align 1352; TUNIT-NEXT: br label [[M]]353; TUNIT: m:354; TUNIT-NEXT: [[L:%.*]] = load i1, ptr [[STACK]], align 1355; TUNIT-NEXT: call void @llvm.assume(i1 noundef [[L]]) #[[ATTR7]]356; TUNIT-NEXT: ret i1 [[L]]357;358; CGSCC: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(inaccessiblemem: readwrite)359; CGSCC-LABEL: define {{[^@]+}}@assume_2_nr360; CGSCC-SAME: (i1 [[ARG:%.*]], i1 noundef [[COND:%.*]]) #[[ATTR4]] {361; CGSCC-NEXT: [[STACK:%.*]] = alloca i1, align 1362; CGSCC-NEXT: br i1 [[COND]], label [[T:%.*]], label [[F:%.*]]363; CGSCC: t:364; CGSCC-NEXT: store i1 true, ptr [[STACK]], align 1365; CGSCC-NEXT: br label [[M:%.*]]366; CGSCC: f:367; CGSCC-NEXT: store i1 false, ptr [[STACK]], align 1368; CGSCC-NEXT: br label [[M]]369; CGSCC: m:370; CGSCC-NEXT: [[L:%.*]] = load i1, ptr [[STACK]], align 1371; CGSCC-NEXT: call void @llvm.assume(i1 noundef [[L]]) #[[ATTR8]]372; CGSCC-NEXT: ret i1 [[L]]373;374 %stack = alloca i1375 store i1 %arg, ptr %stack376 br i1 %cond, label %t, label %f377t:378 store i1 true, ptr %stack379 br label %m380f:381 store i1 false, ptr %stack382 br label %m383m:384 %l = load i1, ptr %stack385 call void @llvm.assume(i1 %l)386 ret i1 %l387}388 389define void @assume_2b_nr(i1 %arg, i1 %cond) norecurse {390; CHECK: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(inaccessiblemem: readwrite)391; CHECK-LABEL: define {{[^@]+}}@assume_2b_nr392; CHECK-SAME: (i1 [[ARG:%.*]], i1 noundef [[COND:%.*]]) #[[ATTR4]] {393; CHECK-NEXT: [[STACK:%.*]] = alloca i1, align 1394; CHECK-NEXT: br i1 [[COND]], label [[T:%.*]], label [[F:%.*]]395; CHECK: t:396; CHECK-NEXT: br label [[M:%.*]]397; CHECK: f:398; CHECK-NEXT: br label [[M]]399; CHECK: m:400; CHECK-NEXT: [[L:%.*]] = load i1, ptr [[STACK]], align 1401; CHECK-NEXT: ret void402;403 %stack = alloca i1404 store i1 %arg, ptr %stack405 br i1 %cond, label %t, label %f406t:407 store i1 true, ptr %stack408 br label %m409f:410 store i1 false, ptr %stack411 br label %m412m:413 %l = load i1, ptr %stack414 call void @llvm.assume(i1 %l)415 ret void416}417 418define i1 @assume_3_nr(i1 %arg, i1 %cond) norecurse {419; TUNIT: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(inaccessiblemem: readwrite)420; TUNIT-LABEL: define {{[^@]+}}@assume_3_nr421; TUNIT-SAME: (i1 [[ARG:%.*]], i1 noundef [[COND:%.*]]) #[[ATTR4]] {422; TUNIT-NEXT: [[STACK:%.*]] = alloca i1, align 1423; TUNIT-NEXT: br i1 [[COND]], label [[T:%.*]], label [[F:%.*]]424; TUNIT: t:425; TUNIT-NEXT: store i1 true, ptr [[STACK]], align 1426; TUNIT-NEXT: br label [[M:%.*]]427; TUNIT: f:428; TUNIT-NEXT: store i1 false, ptr [[STACK]], align 1429; TUNIT-NEXT: br label [[M]]430; TUNIT: m:431; TUNIT-NEXT: [[R:%.*]] = call i1 @readI1p(ptr noalias nofree noundef nonnull readonly captures(none) dereferenceable(1) [[STACK]]) #[[ATTR8:[0-9]+]]432; TUNIT-NEXT: ret i1 [[R]]433;434; CGSCC: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(inaccessiblemem: readwrite)435; CGSCC-LABEL: define {{[^@]+}}@assume_3_nr436; CGSCC-SAME: (i1 [[ARG:%.*]], i1 noundef [[COND:%.*]]) #[[ATTR4]] {437; CGSCC-NEXT: [[STACK:%.*]] = alloca i1, align 1438; CGSCC-NEXT: store i1 [[ARG]], ptr [[STACK]], align 1439; CGSCC-NEXT: [[L:%.*]] = load i1, ptr [[STACK]], align 1440; CGSCC-NEXT: call void @llvm.assume(i1 noundef [[L]]) #[[ATTR8]]441; CGSCC-NEXT: br i1 [[COND]], label [[T:%.*]], label [[F:%.*]]442; CGSCC: t:443; CGSCC-NEXT: store i1 true, ptr [[STACK]], align 1444; CGSCC-NEXT: br label [[M:%.*]]445; CGSCC: f:446; CGSCC-NEXT: store i1 false, ptr [[STACK]], align 1447; CGSCC-NEXT: br label [[M]]448; CGSCC: m:449; CGSCC-NEXT: [[R:%.*]] = call i1 @readI1p(ptr noalias nofree noundef nonnull readonly captures(none) dereferenceable(1) [[STACK]]) #[[ATTR9:[0-9]+]]450; CGSCC-NEXT: ret i1 [[R]]451;452 %stack = alloca i1453 store i1 %arg, ptr %stack454 %l = load i1, ptr %stack455 call void @llvm.assume(i1 %l)456 br i1 %cond, label %t, label %f457t:458 store i1 true, ptr %stack459 br label %m460f:461 store i1 false, ptr %stack462 br label %m463m:464 %r = call i1 @readI1p(ptr %stack)465 ret i1 %r466}467 468define i1 @assume_4_nr(i1 %arg, i1 %cond) norecurse {469; TUNIT: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(inaccessiblemem: readwrite)470; TUNIT-LABEL: define {{[^@]+}}@assume_4_nr471; TUNIT-SAME: (i1 [[ARG:%.*]], i1 noundef [[COND:%.*]]) #[[ATTR4]] {472; TUNIT-NEXT: [[STACK:%.*]] = alloca i1, align 1473; TUNIT-NEXT: br i1 [[COND]], label [[T:%.*]], label [[F:%.*]]474; TUNIT: t:475; TUNIT-NEXT: store i1 true, ptr [[STACK]], align 1476; TUNIT-NEXT: br label [[M:%.*]]477; TUNIT: f:478; TUNIT-NEXT: store i1 false, ptr [[STACK]], align 1479; TUNIT-NEXT: br label [[M]]480; TUNIT: m:481; TUNIT-NEXT: [[L:%.*]] = load i1, ptr [[STACK]], align 1482; TUNIT-NEXT: call void @llvm.assume(i1 noundef [[L]]) #[[ATTR7]]483; TUNIT-NEXT: [[R:%.*]] = call i1 @readI1p(ptr noalias nofree noundef nonnull readonly captures(none) dereferenceable(1) [[STACK]]) #[[ATTR8]]484; TUNIT-NEXT: ret i1 [[R]]485;486; CGSCC: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(inaccessiblemem: readwrite)487; CGSCC-LABEL: define {{[^@]+}}@assume_4_nr488; CGSCC-SAME: (i1 [[ARG:%.*]], i1 noundef [[COND:%.*]]) #[[ATTR4]] {489; CGSCC-NEXT: [[STACK:%.*]] = alloca i1, align 1490; CGSCC-NEXT: store i1 [[ARG]], ptr [[STACK]], align 1491; CGSCC-NEXT: br i1 [[COND]], label [[T:%.*]], label [[F:%.*]]492; CGSCC: t:493; CGSCC-NEXT: store i1 true, ptr [[STACK]], align 1494; CGSCC-NEXT: br label [[M:%.*]]495; CGSCC: f:496; CGSCC-NEXT: store i1 false, ptr [[STACK]], align 1497; CGSCC-NEXT: br label [[M]]498; CGSCC: m:499; CGSCC-NEXT: [[L:%.*]] = load i1, ptr [[STACK]], align 1500; CGSCC-NEXT: call void @llvm.assume(i1 noundef [[L]]) #[[ATTR8]]501; CGSCC-NEXT: [[R:%.*]] = call i1 @readI1p(ptr noalias nofree noundef nonnull readonly captures(none) dereferenceable(1) [[STACK]]) #[[ATTR9]]502; CGSCC-NEXT: ret i1 [[R]]503;504 %stack = alloca i1505 store i1 %arg, ptr %stack506 br i1 %cond, label %t, label %f507t:508 store i1 true, ptr %stack509 br label %m510f:511 store i1 false, ptr %stack512 br label %m513m:514 %l = load i1, ptr %stack515 call void @llvm.assume(i1 %l)516 %r = call i1 @readI1p(ptr %stack)517 ret i1 %r518}519 520define i1 @assume_5_nr(i1 %arg, i1 %cond) norecurse {521; TUNIT: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(inaccessiblemem: readwrite)522; TUNIT-LABEL: define {{[^@]+}}@assume_5_nr523; TUNIT-SAME: (i1 [[ARG:%.*]], i1 noundef [[COND:%.*]]) #[[ATTR4]] {524; TUNIT-NEXT: [[STACK:%.*]] = alloca i1, align 1525; TUNIT-NEXT: br i1 [[COND]], label [[T:%.*]], label [[F:%.*]]526; TUNIT: t:527; TUNIT-NEXT: store i1 true, ptr [[STACK]], align 1528; TUNIT-NEXT: [[L2:%.*]] = load i1, ptr [[STACK]], align 1529; TUNIT-NEXT: call void @llvm.assume(i1 noundef [[L2]]) #[[ATTR7]]530; TUNIT-NEXT: br label [[M:%.*]]531; TUNIT: f:532; TUNIT-NEXT: store i1 false, ptr [[STACK]], align 1533; TUNIT-NEXT: [[L3:%.*]] = load i1, ptr [[STACK]], align 1534; TUNIT-NEXT: call void @llvm.assume(i1 noundef [[L3]]) #[[ATTR7]]535; TUNIT-NEXT: br label [[M]]536; TUNIT: m:537; TUNIT-NEXT: [[L4:%.*]] = load i1, ptr [[STACK]], align 1538; TUNIT-NEXT: call void @llvm.assume(i1 noundef [[L4]]) #[[ATTR9:[0-9]+]]539; TUNIT-NEXT: [[R:%.*]] = call i1 @readI1p(ptr noalias nofree noundef nonnull readonly captures(none) dereferenceable(1) [[STACK]]) #[[ATTR8]]540; TUNIT-NEXT: ret i1 [[R]]541;542; CGSCC: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(inaccessiblemem: readwrite)543; CGSCC-LABEL: define {{[^@]+}}@assume_5_nr544; CGSCC-SAME: (i1 [[ARG:%.*]], i1 noundef [[COND:%.*]]) #[[ATTR4]] {545; CGSCC-NEXT: [[STACK:%.*]] = alloca i1, align 1546; CGSCC-NEXT: store i1 [[ARG]], ptr [[STACK]], align 1547; CGSCC-NEXT: [[L1:%.*]] = load i1, ptr [[STACK]], align 1548; CGSCC-NEXT: call void @llvm.assume(i1 noundef [[L1]]) #[[ATTR8]]549; CGSCC-NEXT: br i1 [[COND]], label [[T:%.*]], label [[F:%.*]]550; CGSCC: t:551; CGSCC-NEXT: store i1 true, ptr [[STACK]], align 1552; CGSCC-NEXT: [[L2:%.*]] = load i1, ptr [[STACK]], align 1553; CGSCC-NEXT: call void @llvm.assume(i1 noundef [[L2]]) #[[ATTR10:[0-9]+]]554; CGSCC-NEXT: br label [[M:%.*]]555; CGSCC: f:556; CGSCC-NEXT: store i1 false, ptr [[STACK]], align 1557; CGSCC-NEXT: [[L3:%.*]] = load i1, ptr [[STACK]], align 1558; CGSCC-NEXT: call void @llvm.assume(i1 noundef [[L3]]) #[[ATTR10]]559; CGSCC-NEXT: br label [[M]]560; CGSCC: m:561; CGSCC-NEXT: [[L4:%.*]] = load i1, ptr [[STACK]], align 1562; CGSCC-NEXT: call void @llvm.assume(i1 noundef [[L4]]) #[[ATTR10]]563; CGSCC-NEXT: [[R:%.*]] = call i1 @readI1p(ptr noalias nofree noundef nonnull readonly captures(none) dereferenceable(1) [[STACK]]) #[[ATTR10]]564; CGSCC-NEXT: ret i1 [[R]]565;566 %stack = alloca i1567 store i1 %arg, ptr %stack568 %l1 = load i1, ptr %stack569 call void @llvm.assume(i1 %l1)570 br i1 %cond, label %t, label %f571t:572 store i1 true, ptr %stack573 %l2 = load i1, ptr %stack574 call void @llvm.assume(i1 %l2)575 br label %m576f:577 store i1 false, ptr %stack578 %l3 = load i1, ptr %stack579 call void @llvm.assume(i1 %l3)580 br label %m581m:582 %l4 = load i1, ptr %stack583 call void @llvm.assume(i1 %l4)584 %r = call i1 @readI1p(ptr %stack)585 ret i1 %r586}587 588define i1 @assume_5c_nr(i1 %cond) norecurse {589; TUNIT: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(inaccessiblemem: readwrite)590; TUNIT-LABEL: define {{[^@]+}}@assume_5c_nr591; TUNIT-SAME: (i1 noundef [[COND:%.*]]) #[[ATTR4]] {592; TUNIT-NEXT: [[STACK:%.*]] = alloca i1, align 1593; TUNIT-NEXT: call void @llvm.assume(i1 noundef true) #[[ATTR7]]594; TUNIT-NEXT: br i1 [[COND]], label [[T:%.*]], label [[F:%.*]]595; TUNIT: t:596; TUNIT-NEXT: store i1 true, ptr [[STACK]], align 1597; TUNIT-NEXT: [[L2:%.*]] = load i1, ptr [[STACK]], align 1598; TUNIT-NEXT: call void @llvm.assume(i1 noundef [[L2]]) #[[ATTR7]]599; TUNIT-NEXT: br label [[M:%.*]]600; TUNIT: f:601; TUNIT-NEXT: store i1 false, ptr [[STACK]], align 1602; TUNIT-NEXT: [[L3:%.*]] = load i1, ptr [[STACK]], align 1603; TUNIT-NEXT: call void @llvm.assume(i1 noundef [[L3]]) #[[ATTR7]]604; TUNIT-NEXT: br label [[M]]605; TUNIT: m:606; TUNIT-NEXT: [[L4:%.*]] = load i1, ptr [[STACK]], align 1607; TUNIT-NEXT: call void @llvm.assume(i1 noundef [[L4]]) #[[ATTR9]]608; TUNIT-NEXT: [[R:%.*]] = call i1 @readI1p(ptr noalias nofree noundef nonnull readonly captures(none) dereferenceable(1) [[STACK]]) #[[ATTR8]]609; TUNIT-NEXT: ret i1 [[R]]610;611; CGSCC: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(inaccessiblemem: readwrite)612; CGSCC-LABEL: define {{[^@]+}}@assume_5c_nr613; CGSCC-SAME: (i1 noundef [[COND:%.*]]) #[[ATTR4]] {614; CGSCC-NEXT: [[STACK:%.*]] = alloca i1, align 1615; CGSCC-NEXT: store i1 true, ptr [[STACK]], align 1616; CGSCC-NEXT: [[L1:%.*]] = load i1, ptr [[STACK]], align 1617; CGSCC-NEXT: call void @llvm.assume(i1 noundef [[L1]]) #[[ATTR8]]618; CGSCC-NEXT: br i1 [[COND]], label [[T:%.*]], label [[F:%.*]]619; CGSCC: t:620; CGSCC-NEXT: store i1 true, ptr [[STACK]], align 1621; CGSCC-NEXT: [[L2:%.*]] = load i1, ptr [[STACK]], align 1622; CGSCC-NEXT: call void @llvm.assume(i1 noundef [[L2]]) #[[ATTR10]]623; CGSCC-NEXT: br label [[M:%.*]]624; CGSCC: f:625; CGSCC-NEXT: store i1 false, ptr [[STACK]], align 1626; CGSCC-NEXT: [[L3:%.*]] = load i1, ptr [[STACK]], align 1627; CGSCC-NEXT: call void @llvm.assume(i1 noundef [[L3]]) #[[ATTR10]]628; CGSCC-NEXT: br label [[M]]629; CGSCC: m:630; CGSCC-NEXT: [[L4:%.*]] = load i1, ptr [[STACK]], align 1631; CGSCC-NEXT: call void @llvm.assume(i1 noundef [[L4]]) #[[ATTR10]]632; CGSCC-NEXT: [[R:%.*]] = call i1 @readI1p(ptr noalias nofree noundef nonnull readonly captures(none) dereferenceable(1) [[STACK]]) #[[ATTR10]]633; CGSCC-NEXT: ret i1 [[R]]634;635 %stack = alloca i1636 store i1 true, ptr %stack637 %l1 = load i1, ptr %stack638 call void @llvm.assume(i1 %l1)639 br i1 %cond, label %t, label %f640t:641 store i1 true, ptr %stack642 %l2 = load i1, ptr %stack643 call void @llvm.assume(i1 %l2)644 br label %m645f:646 store i1 false, ptr %stack647 %l3 = load i1, ptr %stack648 call void @llvm.assume(i1 %l3)649 br label %m650m:651 %l4 = load i1, ptr %stack652 call void @llvm.assume(i1 %l4)653 %r = call i1 @readI1p(ptr %stack)654 ret i1 %r655}656 657 658define i1 @keep_assume_1c() {659; CHECK-LABEL: define {{[^@]+}}@keep_assume_1c() {660; CHECK-NEXT: [[STACK:%.*]] = alloca i1, align 1661; CHECK-NEXT: store i1 true, ptr [[STACK]], align 1662; CHECK-NEXT: call void @useI1p(ptr noundef nonnull dereferenceable(1) [[STACK]])663; CHECK-NEXT: [[L:%.*]] = load i1, ptr [[STACK]], align 1664; CHECK-NEXT: call void @llvm.assume(i1 noundef [[L]])665; CHECK-NEXT: ret i1 [[L]]666;667 %stack = alloca i1668 store i1 true, ptr %stack669 call void @useI1p(ptr %stack)670 %l = load i1, ptr %stack671 call void @llvm.assume(i1 %l)672 ret i1 %l673}674 675define i1 @drop_assume_1c() {676; TUNIT: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(inaccessiblemem: write)677; TUNIT-LABEL: define {{[^@]+}}@drop_assume_1c678; TUNIT-SAME: () #[[ATTR3]] {679; TUNIT-NEXT: call void @llvm.assume(i1 noundef true) #[[ATTR7]]680; TUNIT-NEXT: ret i1 true681;682; CGSCC: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(inaccessiblemem: write)683; CGSCC-LABEL: define {{[^@]+}}@drop_assume_1c684; CGSCC-SAME: () #[[ATTR3]] {685; CGSCC-NEXT: call void @llvm.assume(i1 noundef true) #[[ATTR8]]686; CGSCC-NEXT: ret i1 true687;688 %stack = alloca i1689 store i1 true, ptr %stack690 %l = load i1, ptr %stack691 call void @llvm.assume(i1 %l)692 ret i1 %l693}694 695define i1 @keep_assume_2c() {696; CHECK-LABEL: define {{[^@]+}}@keep_assume_2c() {697; CHECK-NEXT: [[STACK:%.*]] = alloca i1, align 1698; CHECK-NEXT: store i1 true, ptr [[STACK]], align 1699; CHECK-NEXT: call void @useI1p(ptr noundef nonnull dereferenceable(1) [[STACK]])700; CHECK-NEXT: [[L1:%.*]] = load i1, ptr [[STACK]], align 1701; CHECK-NEXT: call void @llvm.assume(i1 noundef [[L1]])702; CHECK-NEXT: call void @unknown()703; CHECK-NEXT: [[L2:%.*]] = load i1, ptr [[STACK]], align 1704; CHECK-NEXT: ret i1 [[L2]]705;706 %stack = alloca i1707 store i1 true, ptr %stack708 call void @useI1p(ptr %stack)709 %l1 = load i1, ptr %stack710 call void @llvm.assume(i1 %l1)711 call void @unknown()712 %l2 = load i1, ptr %stack713 ret i1 %l2714}715 716define i1 @keep_assume_3c() {717;718; TUNIT-LABEL: define {{[^@]+}}@keep_assume_3c() {719; TUNIT-NEXT: [[STACK:%.*]] = alloca i1, align 1720; TUNIT-NEXT: store i1 true, ptr [[STACK]], align 1721; TUNIT-NEXT: [[L:%.*]] = load i1, ptr [[STACK]], align 1722; TUNIT-NEXT: call void @llvm.assume(i1 noundef [[L]]) #[[ATTR7]]723; TUNIT-NEXT: call void @useI1p(ptr noundef nonnull dereferenceable(1) [[STACK]])724; TUNIT-NEXT: ret i1 [[L]]725;726; CGSCC-LABEL: define {{[^@]+}}@keep_assume_3c() {727; CGSCC-NEXT: [[STACK:%.*]] = alloca i1, align 1728; CGSCC-NEXT: store i1 true, ptr [[STACK]], align 1729; CGSCC-NEXT: [[L:%.*]] = load i1, ptr [[STACK]], align 1730; CGSCC-NEXT: call void @llvm.assume(i1 noundef [[L]]) #[[ATTR8]]731; CGSCC-NEXT: call void @useI1p(ptr noundef nonnull dereferenceable(1) [[STACK]])732; CGSCC-NEXT: ret i1 [[L]]733;734 %stack = alloca i1735 store i1 true, ptr %stack736 %l = load i1, ptr %stack737 call void @llvm.assume(i1 %l)738 call void @useI1p(ptr %stack)739 ret i1 %l740}741define i1 @keep_assume_4c() {742;743; TUNIT-LABEL: define {{[^@]+}}@keep_assume_4c() {744; TUNIT-NEXT: [[STACK:%.*]] = alloca i1, align 1745; TUNIT-NEXT: store i1 true, ptr [[STACK]], align 1746; TUNIT-NEXT: [[L4:%.*]] = load i1, ptr [[STACK]], align 1747; TUNIT-NEXT: call void @llvm.assume(i1 noundef [[L4]]) #[[ATTR7]]748; TUNIT-NEXT: call void @useI1p(ptr noalias noundef nonnull captures(none) dereferenceable(1) [[STACK]])749; TUNIT-NEXT: ret i1 [[L4]]750;751; CGSCC-LABEL: define {{[^@]+}}@keep_assume_4c() {752; CGSCC-NEXT: [[STACK:%.*]] = alloca i1, align 1753; CGSCC-NEXT: store i1 true, ptr [[STACK]], align 1754; CGSCC-NEXT: [[L4:%.*]] = load i1, ptr [[STACK]], align 1755; CGSCC-NEXT: call void @llvm.assume(i1 noundef [[L4]]) #[[ATTR8]]756; CGSCC-NEXT: call void @useI1p(ptr noalias noundef nonnull captures(none) dereferenceable(1) [[STACK]])757; CGSCC-NEXT: ret i1 [[L4]]758;759 %stack = alloca i1760 store i1 true, ptr %stack761 %l4 = load i1, ptr %stack762 call void @llvm.assume(i1 %l4)763 call void @useI1p(ptr nocapture %stack)764 ret i1 %l4765}766 767define i1 @keep_assume_1(i1 %arg) {768; CHECK-LABEL: define {{[^@]+}}@keep_assume_1769; CHECK-SAME: (i1 [[ARG:%.*]]) {770; CHECK-NEXT: [[STACK:%.*]] = alloca i1, align 1771; CHECK-NEXT: store i1 [[ARG]], ptr [[STACK]], align 1772; CHECK-NEXT: call void @useI1p(ptr noundef nonnull dereferenceable(1) [[STACK]])773; CHECK-NEXT: [[L:%.*]] = load i1, ptr [[STACK]], align 1774; CHECK-NEXT: call void @llvm.assume(i1 noundef [[L]])775; CHECK-NEXT: ret i1 [[L]]776;777 %stack = alloca i1778 store i1 %arg, ptr %stack779 call void @useI1p(ptr %stack)780 %l = load i1, ptr %stack781 call void @llvm.assume(i1 %l)782 ret i1 %l783}784 785define i1 @drop_assume_1(i1 %arg) {786; TUNIT: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(inaccessiblemem: readwrite)787; TUNIT-LABEL: define {{[^@]+}}@drop_assume_1788; TUNIT-SAME: (i1 returned [[ARG:%.*]]) #[[ATTR4]] {789; TUNIT-NEXT: [[STACK:%.*]] = alloca i1, align 1790; TUNIT-NEXT: store i1 [[ARG]], ptr [[STACK]], align 1791; TUNIT-NEXT: call void @llvm.assume(i1 noundef [[ARG]]) #[[ATTR7]]792; TUNIT-NEXT: ret i1 [[ARG]]793;794; CGSCC: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(inaccessiblemem: readwrite)795; CGSCC-LABEL: define {{[^@]+}}@drop_assume_1796; CGSCC-SAME: (i1 returned [[ARG:%.*]]) #[[ATTR4]] {797; CGSCC-NEXT: [[STACK:%.*]] = alloca i1, align 1798; CGSCC-NEXT: store i1 [[ARG]], ptr [[STACK]], align 1799; CGSCC-NEXT: call void @llvm.assume(i1 noundef [[ARG]]) #[[ATTR8]]800; CGSCC-NEXT: ret i1 [[ARG]]801;802 %stack = alloca i1803 store i1 %arg, ptr %stack804 %l = load i1, ptr %stack805 call void @llvm.assume(i1 %l)806 ret i1 %l807}808 809define i1 @keep_assume_2(i1 %arg) {810; CHECK-LABEL: define {{[^@]+}}@keep_assume_2811; CHECK-SAME: (i1 [[ARG:%.*]]) {812; CHECK-NEXT: [[STACK:%.*]] = alloca i1, align 1813; CHECK-NEXT: store i1 [[ARG]], ptr [[STACK]], align 1814; CHECK-NEXT: call void @useI1p(ptr noundef nonnull dereferenceable(1) [[STACK]])815; CHECK-NEXT: [[L1:%.*]] = load i1, ptr [[STACK]], align 1816; CHECK-NEXT: call void @llvm.assume(i1 noundef [[L1]])817; CHECK-NEXT: call void @unknown()818; CHECK-NEXT: [[L2:%.*]] = load i1, ptr [[STACK]], align 1819; CHECK-NEXT: ret i1 [[L2]]820;821 %stack = alloca i1822 store i1 %arg, ptr %stack823 call void @useI1p(ptr %stack)824 %l1 = load i1, ptr %stack825 call void @llvm.assume(i1 %l1)826 call void @unknown()827 %l2 = load i1, ptr %stack828 ret i1 %l2829}830 831define i1 @keep_assume_3(i1 %arg) {832;833; TUNIT-LABEL: define {{[^@]+}}@keep_assume_3834; TUNIT-SAME: (i1 [[ARG:%.*]]) {835; TUNIT-NEXT: [[STACK:%.*]] = alloca i1, align 1836; TUNIT-NEXT: store i1 [[ARG]], ptr [[STACK]], align 1837; TUNIT-NEXT: [[L:%.*]] = load i1, ptr [[STACK]], align 1838; TUNIT-NEXT: call void @llvm.assume(i1 noundef [[L]]) #[[ATTR7]]839; TUNIT-NEXT: call void @useI1p(ptr noundef nonnull dereferenceable(1) [[STACK]])840; TUNIT-NEXT: ret i1 [[L]]841;842; CGSCC-LABEL: define {{[^@]+}}@keep_assume_3843; CGSCC-SAME: (i1 [[ARG:%.*]]) {844; CGSCC-NEXT: [[STACK:%.*]] = alloca i1, align 1845; CGSCC-NEXT: store i1 [[ARG]], ptr [[STACK]], align 1846; CGSCC-NEXT: [[L:%.*]] = load i1, ptr [[STACK]], align 1847; CGSCC-NEXT: call void @llvm.assume(i1 noundef [[L]]) #[[ATTR8]]848; CGSCC-NEXT: call void @useI1p(ptr noundef nonnull dereferenceable(1) [[STACK]])849; CGSCC-NEXT: ret i1 [[L]]850;851 %stack = alloca i1852 store i1 %arg, ptr %stack853 %l = load i1, ptr %stack854 call void @llvm.assume(i1 %l)855 call void @useI1p(ptr %stack)856 ret i1 %l857}858 859define i1 @keep_assume_4(i1 %arg) {860;861; TUNIT-LABEL: define {{[^@]+}}@keep_assume_4862; TUNIT-SAME: (i1 [[ARG:%.*]]) {863; TUNIT-NEXT: [[STACK:%.*]] = alloca i1, align 1864; TUNIT-NEXT: store i1 [[ARG]], ptr [[STACK]], align 1865; TUNIT-NEXT: [[L:%.*]] = load i1, ptr [[STACK]], align 1866; TUNIT-NEXT: call void @llvm.assume(i1 noundef [[L]]) #[[ATTR7]]867; TUNIT-NEXT: call void @useI1p(ptr noalias noundef nonnull captures(none) dereferenceable(1) [[STACK]])868; TUNIT-NEXT: ret i1 [[L]]869;870; CGSCC-LABEL: define {{[^@]+}}@keep_assume_4871; CGSCC-SAME: (i1 [[ARG:%.*]]) {872; CGSCC-NEXT: [[STACK:%.*]] = alloca i1, align 1873; CGSCC-NEXT: store i1 [[ARG]], ptr [[STACK]], align 1874; CGSCC-NEXT: [[L:%.*]] = load i1, ptr [[STACK]], align 1875; CGSCC-NEXT: call void @llvm.assume(i1 noundef [[L]]) #[[ATTR8]]876; CGSCC-NEXT: call void @useI1p(ptr noalias noundef nonnull captures(none) dereferenceable(1) [[STACK]])877; CGSCC-NEXT: ret i1 [[L]]878;879 %stack = alloca i1880 store i1 %arg, ptr %stack881 %l = load i1, ptr %stack882 call void @llvm.assume(i1 %l)883 call void @useI1p(ptr nocapture %stack)884 ret i1 %l885}886 887define i1 @assume_1(i1 %arg, i1 %cond) {888; TUNIT: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(inaccessiblemem: readwrite)889; TUNIT-LABEL: define {{[^@]+}}@assume_1890; TUNIT-SAME: (i1 returned [[ARG:%.*]], i1 noundef [[COND:%.*]]) #[[ATTR4]] {891; TUNIT-NEXT: [[STACK:%.*]] = alloca i1, align 1892; TUNIT-NEXT: store i1 [[ARG]], ptr [[STACK]], align 1893; TUNIT-NEXT: call void @llvm.assume(i1 noundef [[ARG]]) #[[ATTR7]]894; TUNIT-NEXT: br i1 [[COND]], label [[T:%.*]], label [[F:%.*]]895; TUNIT: t:896; TUNIT-NEXT: br label [[M:%.*]]897; TUNIT: f:898; TUNIT-NEXT: br label [[M]]899; TUNIT: m:900; TUNIT-NEXT: ret i1 [[ARG]]901;902; CGSCC: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(inaccessiblemem: readwrite)903; CGSCC-LABEL: define {{[^@]+}}@assume_1904; CGSCC-SAME: (i1 returned [[ARG:%.*]], i1 noundef [[COND:%.*]]) #[[ATTR4]] {905; CGSCC-NEXT: [[STACK:%.*]] = alloca i1, align 1906; CGSCC-NEXT: store i1 [[ARG]], ptr [[STACK]], align 1907; CGSCC-NEXT: call void @llvm.assume(i1 noundef [[ARG]]) #[[ATTR8]]908; CGSCC-NEXT: br i1 [[COND]], label [[T:%.*]], label [[F:%.*]]909; CGSCC: t:910; CGSCC-NEXT: br label [[M:%.*]]911; CGSCC: f:912; CGSCC-NEXT: br label [[M]]913; CGSCC: m:914; CGSCC-NEXT: ret i1 [[ARG]]915;916 %stack = alloca i1917 store i1 %arg, ptr %stack918 %l = load i1, ptr %stack919 call void @llvm.assume(i1 %l)920 br i1 %cond, label %t, label %f921t:922 store i1 true, ptr %stack923 br label %m924f:925 store i1 false, ptr %stack926 br label %m927m:928 ret i1 %l929}930 931define void @assume_1b(i1 %arg, i1 %cond) {932; CHECK: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(inaccessiblemem: readwrite)933; CHECK-LABEL: define {{[^@]+}}@assume_1b934; CHECK-SAME: (i1 [[ARG:%.*]], i1 noundef [[COND:%.*]]) #[[ATTR4]] {935; CHECK-NEXT: br i1 [[COND]], label [[T:%.*]], label [[F:%.*]]936; CHECK: t:937; CHECK-NEXT: br label [[M:%.*]]938; CHECK: f:939; CHECK-NEXT: br label [[M]]940; CHECK: m:941; CHECK-NEXT: ret void942;943 %stack = alloca i1944 store i1 %arg, ptr %stack945 %l = load i1, ptr %stack946 call void @llvm.assume(i1 %l)947 br i1 %cond, label %t, label %f948t:949 store i1 true, ptr %stack950 br label %m951f:952 store i1 false, ptr %stack953 br label %m954m:955 ret void956}957 958define i1 @assume_2(i1 %arg, i1 %cond) {959; TUNIT: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(inaccessiblemem: readwrite)960; TUNIT-LABEL: define {{[^@]+}}@assume_2961; TUNIT-SAME: (i1 [[ARG:%.*]], i1 noundef [[COND:%.*]]) #[[ATTR4]] {962; TUNIT-NEXT: [[STACK:%.*]] = alloca i1, align 1963; TUNIT-NEXT: br i1 [[COND]], label [[T:%.*]], label [[F:%.*]]964; TUNIT: t:965; TUNIT-NEXT: store i1 true, ptr [[STACK]], align 1966; TUNIT-NEXT: br label [[M:%.*]]967; TUNIT: f:968; TUNIT-NEXT: store i1 false, ptr [[STACK]], align 1969; TUNIT-NEXT: br label [[M]]970; TUNIT: m:971; TUNIT-NEXT: [[L:%.*]] = load i1, ptr [[STACK]], align 1972; TUNIT-NEXT: call void @llvm.assume(i1 noundef [[L]]) #[[ATTR7]]973; TUNIT-NEXT: ret i1 [[L]]974;975; CGSCC: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(inaccessiblemem: readwrite)976; CGSCC-LABEL: define {{[^@]+}}@assume_2977; CGSCC-SAME: (i1 [[ARG:%.*]], i1 noundef [[COND:%.*]]) #[[ATTR4]] {978; CGSCC-NEXT: [[STACK:%.*]] = alloca i1, align 1979; CGSCC-NEXT: br i1 [[COND]], label [[T:%.*]], label [[F:%.*]]980; CGSCC: t:981; CGSCC-NEXT: store i1 true, ptr [[STACK]], align 1982; CGSCC-NEXT: br label [[M:%.*]]983; CGSCC: f:984; CGSCC-NEXT: store i1 false, ptr [[STACK]], align 1985; CGSCC-NEXT: br label [[M]]986; CGSCC: m:987; CGSCC-NEXT: [[L:%.*]] = load i1, ptr [[STACK]], align 1988; CGSCC-NEXT: call void @llvm.assume(i1 noundef [[L]]) #[[ATTR8]]989; CGSCC-NEXT: ret i1 [[L]]990;991 %stack = alloca i1992 store i1 %arg, ptr %stack993 br i1 %cond, label %t, label %f994t:995 store i1 true, ptr %stack996 br label %m997f:998 store i1 false, ptr %stack999 br label %m1000m:1001 %l = load i1, ptr %stack1002 call void @llvm.assume(i1 %l)1003 ret i1 %l1004}1005 1006define void @assume_2b(i1 %arg, i1 %cond) {1007; CHECK: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(inaccessiblemem: readwrite)1008; CHECK-LABEL: define {{[^@]+}}@assume_2b1009; CHECK-SAME: (i1 [[ARG:%.*]], i1 noundef [[COND:%.*]]) #[[ATTR4]] {1010; CHECK-NEXT: [[STACK:%.*]] = alloca i1, align 11011; CHECK-NEXT: br i1 [[COND]], label [[T:%.*]], label [[F:%.*]]1012; CHECK: t:1013; CHECK-NEXT: br label [[M:%.*]]1014; CHECK: f:1015; CHECK-NEXT: br label [[M]]1016; CHECK: m:1017; CHECK-NEXT: [[L:%.*]] = load i1, ptr [[STACK]], align 11018; CHECK-NEXT: ret void1019;1020 %stack = alloca i11021 store i1 %arg, ptr %stack1022 br i1 %cond, label %t, label %f1023t:1024 store i1 true, ptr %stack1025 br label %m1026f:1027 store i1 false, ptr %stack1028 br label %m1029m:1030 %l = load i1, ptr %stack1031 call void @llvm.assume(i1 %l)1032 ret void1033}1034 1035define i1 @assume_3(i1 %arg, i1 %cond) {1036; TUNIT: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(inaccessiblemem: readwrite)1037; TUNIT-LABEL: define {{[^@]+}}@assume_31038; TUNIT-SAME: (i1 [[ARG:%.*]], i1 noundef [[COND:%.*]]) #[[ATTR4]] {1039; TUNIT-NEXT: [[STACK:%.*]] = alloca i1, align 11040; TUNIT-NEXT: br i1 [[COND]], label [[T:%.*]], label [[F:%.*]]1041; TUNIT: t:1042; TUNIT-NEXT: store i1 true, ptr [[STACK]], align 11043; TUNIT-NEXT: br label [[M:%.*]]1044; TUNIT: f:1045; TUNIT-NEXT: store i1 false, ptr [[STACK]], align 11046; TUNIT-NEXT: br label [[M]]1047; TUNIT: m:1048; TUNIT-NEXT: [[R:%.*]] = call i1 @readI1p(ptr noalias nofree noundef nonnull readonly captures(none) dereferenceable(1) [[STACK]]) #[[ATTR8]]1049; TUNIT-NEXT: ret i1 [[R]]1050;1051; CGSCC: Function Attrs: mustprogress nofree nosync nounwind willreturn memory(inaccessiblemem: readwrite)1052; CGSCC-LABEL: define {{[^@]+}}@assume_31053; CGSCC-SAME: (i1 [[ARG:%.*]], i1 noundef [[COND:%.*]]) #[[ATTR5:[0-9]+]] {1054; CGSCC-NEXT: [[STACK:%.*]] = alloca i1, align 11055; CGSCC-NEXT: store i1 [[ARG]], ptr [[STACK]], align 11056; CGSCC-NEXT: [[L:%.*]] = load i1, ptr [[STACK]], align 11057; CGSCC-NEXT: call void @llvm.assume(i1 noundef [[L]]) #[[ATTR8]]1058; CGSCC-NEXT: br i1 [[COND]], label [[T:%.*]], label [[F:%.*]]1059; CGSCC: t:1060; CGSCC-NEXT: store i1 true, ptr [[STACK]], align 11061; CGSCC-NEXT: br label [[M:%.*]]1062; CGSCC: f:1063; CGSCC-NEXT: store i1 false, ptr [[STACK]], align 11064; CGSCC-NEXT: br label [[M]]1065; CGSCC: m:1066; CGSCC-NEXT: [[R:%.*]] = call i1 @readI1p(ptr noalias nofree noundef nonnull readonly captures(none) dereferenceable(1) [[STACK]]) #[[ATTR9]]1067; CGSCC-NEXT: ret i1 [[R]]1068;1069 %stack = alloca i11070 store i1 %arg, ptr %stack1071 %l = load i1, ptr %stack1072 call void @llvm.assume(i1 %l)1073 br i1 %cond, label %t, label %f1074t:1075 store i1 true, ptr %stack1076 br label %m1077f:1078 store i1 false, ptr %stack1079 br label %m1080m:1081 %r = call i1 @readI1p(ptr %stack)1082 ret i1 %r1083}1084 1085define i1 @assume_4(i1 %arg, i1 %cond) {1086; TUNIT: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(inaccessiblemem: readwrite)1087; TUNIT-LABEL: define {{[^@]+}}@assume_41088; TUNIT-SAME: (i1 [[ARG:%.*]], i1 noundef [[COND:%.*]]) #[[ATTR4]] {1089; TUNIT-NEXT: [[STACK:%.*]] = alloca i1, align 11090; TUNIT-NEXT: br i1 [[COND]], label [[T:%.*]], label [[F:%.*]]1091; TUNIT: t:1092; TUNIT-NEXT: store i1 true, ptr [[STACK]], align 11093; TUNIT-NEXT: br label [[M:%.*]]1094; TUNIT: f:1095; TUNIT-NEXT: store i1 false, ptr [[STACK]], align 11096; TUNIT-NEXT: br label [[M]]1097; TUNIT: m:1098; TUNIT-NEXT: [[L:%.*]] = load i1, ptr [[STACK]], align 11099; TUNIT-NEXT: call void @llvm.assume(i1 noundef [[L]]) #[[ATTR7]]1100; TUNIT-NEXT: [[R:%.*]] = call i1 @readI1p(ptr noalias nofree noundef nonnull readonly captures(none) dereferenceable(1) [[STACK]]) #[[ATTR8]]1101; TUNIT-NEXT: ret i1 [[R]]1102;1103; CGSCC: Function Attrs: mustprogress nofree nosync nounwind willreturn memory(inaccessiblemem: readwrite)1104; CGSCC-LABEL: define {{[^@]+}}@assume_41105; CGSCC-SAME: (i1 [[ARG:%.*]], i1 noundef [[COND:%.*]]) #[[ATTR5]] {1106; CGSCC-NEXT: [[STACK:%.*]] = alloca i1, align 11107; CGSCC-NEXT: store i1 [[ARG]], ptr [[STACK]], align 11108; CGSCC-NEXT: br i1 [[COND]], label [[T:%.*]], label [[F:%.*]]1109; CGSCC: t:1110; CGSCC-NEXT: store i1 true, ptr [[STACK]], align 11111; CGSCC-NEXT: br label [[M:%.*]]1112; CGSCC: f:1113; CGSCC-NEXT: store i1 false, ptr [[STACK]], align 11114; CGSCC-NEXT: br label [[M]]1115; CGSCC: m:1116; CGSCC-NEXT: [[L:%.*]] = load i1, ptr [[STACK]], align 11117; CGSCC-NEXT: call void @llvm.assume(i1 noundef [[L]]) #[[ATTR8]]1118; CGSCC-NEXT: [[R:%.*]] = call i1 @readI1p(ptr noalias nofree noundef nonnull readonly captures(none) dereferenceable(1) [[STACK]]) #[[ATTR9]]1119; CGSCC-NEXT: ret i1 [[R]]1120;1121 %stack = alloca i11122 store i1 %arg, ptr %stack1123 br i1 %cond, label %t, label %f1124t:1125 store i1 true, ptr %stack1126 br label %m1127f:1128 store i1 false, ptr %stack1129 br label %m1130m:1131 %l = load i1, ptr %stack1132 call void @llvm.assume(i1 %l)1133 %r = call i1 @readI1p(ptr %stack)1134 ret i1 %r1135}1136 1137define i1 @assume_5(i1 %arg, i1 %cond) {1138; TUNIT: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(inaccessiblemem: readwrite)1139; TUNIT-LABEL: define {{[^@]+}}@assume_51140; TUNIT-SAME: (i1 [[ARG:%.*]], i1 noundef [[COND:%.*]]) #[[ATTR4]] {1141; TUNIT-NEXT: [[STACK:%.*]] = alloca i1, align 11142; TUNIT-NEXT: br i1 [[COND]], label [[T:%.*]], label [[F:%.*]]1143; TUNIT: t:1144; TUNIT-NEXT: store i1 true, ptr [[STACK]], align 11145; TUNIT-NEXT: [[L2:%.*]] = load i1, ptr [[STACK]], align 11146; TUNIT-NEXT: call void @llvm.assume(i1 noundef [[L2]]) #[[ATTR7]]1147; TUNIT-NEXT: br label [[M:%.*]]1148; TUNIT: f:1149; TUNIT-NEXT: store i1 false, ptr [[STACK]], align 11150; TUNIT-NEXT: [[L3:%.*]] = load i1, ptr [[STACK]], align 11151; TUNIT-NEXT: call void @llvm.assume(i1 noundef [[L3]]) #[[ATTR7]]1152; TUNIT-NEXT: br label [[M]]1153; TUNIT: m:1154; TUNIT-NEXT: [[L4:%.*]] = load i1, ptr [[STACK]], align 11155; TUNIT-NEXT: call void @llvm.assume(i1 noundef [[L4]]) #[[ATTR9]]1156; TUNIT-NEXT: [[R:%.*]] = call i1 @readI1p(ptr noalias nofree noundef nonnull readonly captures(none) dereferenceable(1) [[STACK]]) #[[ATTR8]]1157; TUNIT-NEXT: ret i1 [[R]]1158;1159; CGSCC: Function Attrs: mustprogress nofree nosync nounwind willreturn memory(inaccessiblemem: readwrite)1160; CGSCC-LABEL: define {{[^@]+}}@assume_51161; CGSCC-SAME: (i1 [[ARG:%.*]], i1 noundef [[COND:%.*]]) #[[ATTR5]] {1162; CGSCC-NEXT: [[STACK:%.*]] = alloca i1, align 11163; CGSCC-NEXT: store i1 [[ARG]], ptr [[STACK]], align 11164; CGSCC-NEXT: [[L1:%.*]] = load i1, ptr [[STACK]], align 11165; CGSCC-NEXT: call void @llvm.assume(i1 noundef [[L1]]) #[[ATTR8]]1166; CGSCC-NEXT: br i1 [[COND]], label [[T:%.*]], label [[F:%.*]]1167; CGSCC: t:1168; CGSCC-NEXT: store i1 true, ptr [[STACK]], align 11169; CGSCC-NEXT: [[L2:%.*]] = load i1, ptr [[STACK]], align 11170; CGSCC-NEXT: call void @llvm.assume(i1 noundef [[L2]]) #[[ATTR10]]1171; CGSCC-NEXT: br label [[M:%.*]]1172; CGSCC: f:1173; CGSCC-NEXT: store i1 false, ptr [[STACK]], align 11174; CGSCC-NEXT: [[L3:%.*]] = load i1, ptr [[STACK]], align 11175; CGSCC-NEXT: call void @llvm.assume(i1 noundef [[L3]]) #[[ATTR10]]1176; CGSCC-NEXT: br label [[M]]1177; CGSCC: m:1178; CGSCC-NEXT: [[L4:%.*]] = load i1, ptr [[STACK]], align 11179; CGSCC-NEXT: call void @llvm.assume(i1 noundef [[L4]]) #[[ATTR10]]1180; CGSCC-NEXT: [[R:%.*]] = call i1 @readI1p(ptr noalias nofree noundef nonnull readonly captures(none) dereferenceable(1) [[STACK]]) #[[ATTR10]]1181; CGSCC-NEXT: ret i1 [[R]]1182;1183 %stack = alloca i11184 store i1 %arg, ptr %stack1185 %l1 = load i1, ptr %stack1186 call void @llvm.assume(i1 %l1)1187 br i1 %cond, label %t, label %f1188t:1189 store i1 true, ptr %stack1190 %l2 = load i1, ptr %stack1191 call void @llvm.assume(i1 %l2)1192 br label %m1193f:1194 store i1 false, ptr %stack1195 %l3 = load i1, ptr %stack1196 call void @llvm.assume(i1 %l3)1197 br label %m1198m:1199 %l4 = load i1, ptr %stack1200 call void @llvm.assume(i1 %l4)1201 %r = call i1 @readI1p(ptr %stack)1202 ret i1 %r1203}1204 1205define i1 @assume_5c(i1 %cond) {1206; TUNIT: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(inaccessiblemem: readwrite)1207; TUNIT-LABEL: define {{[^@]+}}@assume_5c1208; TUNIT-SAME: (i1 noundef [[COND:%.*]]) #[[ATTR4]] {1209; TUNIT-NEXT: [[STACK:%.*]] = alloca i1, align 11210; TUNIT-NEXT: call void @llvm.assume(i1 noundef true) #[[ATTR7]]1211; TUNIT-NEXT: br i1 [[COND]], label [[T:%.*]], label [[F:%.*]]1212; TUNIT: t:1213; TUNIT-NEXT: store i1 true, ptr [[STACK]], align 11214; TUNIT-NEXT: [[L2:%.*]] = load i1, ptr [[STACK]], align 11215; TUNIT-NEXT: call void @llvm.assume(i1 noundef [[L2]]) #[[ATTR7]]1216; TUNIT-NEXT: br label [[M:%.*]]1217; TUNIT: f:1218; TUNIT-NEXT: store i1 false, ptr [[STACK]], align 11219; TUNIT-NEXT: [[L3:%.*]] = load i1, ptr [[STACK]], align 11220; TUNIT-NEXT: call void @llvm.assume(i1 noundef [[L3]]) #[[ATTR7]]1221; TUNIT-NEXT: br label [[M]]1222; TUNIT: m:1223; TUNIT-NEXT: [[L4:%.*]] = load i1, ptr [[STACK]], align 11224; TUNIT-NEXT: call void @llvm.assume(i1 noundef [[L4]]) #[[ATTR9]]1225; TUNIT-NEXT: [[R:%.*]] = call i1 @readI1p(ptr noalias nofree noundef nonnull readonly captures(none) dereferenceable(1) [[STACK]]) #[[ATTR8]]1226; TUNIT-NEXT: ret i1 [[R]]1227;1228; CGSCC: Function Attrs: mustprogress nofree nosync nounwind willreturn memory(inaccessiblemem: readwrite)1229; CGSCC-LABEL: define {{[^@]+}}@assume_5c1230; CGSCC-SAME: (i1 noundef [[COND:%.*]]) #[[ATTR5]] {1231; CGSCC-NEXT: [[STACK:%.*]] = alloca i1, align 11232; CGSCC-NEXT: store i1 true, ptr [[STACK]], align 11233; CGSCC-NEXT: [[L1:%.*]] = load i1, ptr [[STACK]], align 11234; CGSCC-NEXT: call void @llvm.assume(i1 noundef [[L1]]) #[[ATTR8]]1235; CGSCC-NEXT: br i1 [[COND]], label [[T:%.*]], label [[F:%.*]]1236; CGSCC: t:1237; CGSCC-NEXT: store i1 true, ptr [[STACK]], align 11238; CGSCC-NEXT: [[L2:%.*]] = load i1, ptr [[STACK]], align 11239; CGSCC-NEXT: call void @llvm.assume(i1 noundef [[L2]]) #[[ATTR10]]1240; CGSCC-NEXT: br label [[M:%.*]]1241; CGSCC: f:1242; CGSCC-NEXT: store i1 false, ptr [[STACK]], align 11243; CGSCC-NEXT: [[L3:%.*]] = load i1, ptr [[STACK]], align 11244; CGSCC-NEXT: call void @llvm.assume(i1 noundef [[L3]]) #[[ATTR10]]1245; CGSCC-NEXT: br label [[M]]1246; CGSCC: m:1247; CGSCC-NEXT: [[L4:%.*]] = load i1, ptr [[STACK]], align 11248; CGSCC-NEXT: call void @llvm.assume(i1 noundef [[L4]]) #[[ATTR10]]1249; CGSCC-NEXT: [[R:%.*]] = call i1 @readI1p(ptr noalias nofree noundef nonnull readonly captures(none) dereferenceable(1) [[STACK]]) #[[ATTR10]]1250; CGSCC-NEXT: ret i1 [[R]]1251;1252 %stack = alloca i11253 store i1 true, ptr %stack1254 %l1 = load i1, ptr %stack1255 call void @llvm.assume(i1 %l1)1256 br i1 %cond, label %t, label %f1257t:1258 store i1 true, ptr %stack1259 %l2 = load i1, ptr %stack1260 call void @llvm.assume(i1 %l2)1261 br label %m1262f:1263 store i1 false, ptr %stack1264 %l3 = load i1, ptr %stack1265 call void @llvm.assume(i1 %l3)1266 br label %m1267m:1268 %l4 = load i1, ptr %stack1269 call void @llvm.assume(i1 %l4)1270 %r = call i1 @readI1p(ptr %stack)1271 ret i1 %r1272}1273 1274define i32 @assume_read_global_good() {1275;1276;1277; TUNIT: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn1278; TUNIT-LABEL: define {{[^@]+}}@assume_read_global_good1279; TUNIT-SAME: () #[[ATTR5:[0-9]+]] {1280; TUNIT-NEXT: [[LGS1:%.*]] = load i32, ptr @Gstatic_int1, align 41281; TUNIT-NEXT: [[C:%.*]] = icmp eq i32 [[LGS1]], 421282; TUNIT-NEXT: call void @llvm.assume(i1 noundef [[C]]) #[[ATTR7]]1283; TUNIT-NEXT: [[LGS2:%.*]] = load i32, ptr @Gstatic_int1, align 41284; TUNIT-NEXT: store i32 17, ptr @Gstatic_int1, align 41285; TUNIT-NEXT: [[LGS3:%.*]] = load i32, ptr @Gstatic_int1, align 41286; TUNIT-NEXT: [[ADD:%.*]] = add i32 [[LGS2]], [[LGS3]]1287; TUNIT-NEXT: ret i32 [[ADD]]1288;1289; CGSCC: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn1290; CGSCC-LABEL: define {{[^@]+}}@assume_read_global_good1291; CGSCC-SAME: () #[[ATTR6:[0-9]+]] {1292; CGSCC-NEXT: [[LGS1:%.*]] = load i32, ptr @Gstatic_int1, align 41293; CGSCC-NEXT: [[C:%.*]] = icmp eq i32 [[LGS1]], 421294; CGSCC-NEXT: call void @llvm.assume(i1 noundef [[C]]) #[[ATTR8]]1295; CGSCC-NEXT: [[LGS2:%.*]] = load i32, ptr @Gstatic_int1, align 41296; CGSCC-NEXT: store i32 17, ptr @Gstatic_int1, align 41297; CGSCC-NEXT: [[LGS3:%.*]] = load i32, ptr @Gstatic_int1, align 41298; CGSCC-NEXT: [[ADD:%.*]] = add i32 [[LGS2]], [[LGS3]]1299; CGSCC-NEXT: ret i32 [[ADD]]1300;1301 %lgs1 = load i32, ptr @Gstatic_int11302 %c = icmp eq i32 %lgs1, 421303 call void @llvm.assume(i1 %c)1304 %lgs2 = load i32, ptr @Gstatic_int11305 store i32 13, ptr @Gstatic_int1, align 41306 store i32 17, ptr @Gstatic_int1, align 41307 %lgs3 = load i32, ptr @Gstatic_int11308 %add = add i32 %lgs2, %lgs31309 ret i32 %add1310}1311 1312; TODO: Technically we could still utilize the assumption if we employ AA.1313define i32 @assume_read_global_bad(ptr %p) {1314;1315; TUNIT: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn1316; TUNIT-LABEL: define {{[^@]+}}@assume_read_global_bad1317; TUNIT-SAME: (ptr nofree noundef nonnull writeonly align 4 captures(none) dereferenceable(4) [[P:%.*]]) #[[ATTR5]] {1318; TUNIT-NEXT: [[LGS1:%.*]] = load i32, ptr @Gstatic_int2, align 41319; TUNIT-NEXT: [[C:%.*]] = icmp eq i32 [[LGS1]], 421320; TUNIT-NEXT: store i32 13, ptr [[P]], align 41321; TUNIT-NEXT: call void @llvm.assume(i1 noundef [[C]]) #[[ATTR7]]1322; TUNIT-NEXT: [[LGS2:%.*]] = load i32, ptr @Gstatic_int2, align 41323; TUNIT-NEXT: store i32 17, ptr @Gstatic_int2, align 41324; TUNIT-NEXT: ret i32 [[LGS2]]1325;1326; CGSCC: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn1327; CGSCC-LABEL: define {{[^@]+}}@assume_read_global_bad1328; CGSCC-SAME: (ptr nofree noundef nonnull writeonly align 4 captures(none) dereferenceable(4) [[P:%.*]]) #[[ATTR6]] {1329; CGSCC-NEXT: [[LGS1:%.*]] = load i32, ptr @Gstatic_int2, align 41330; CGSCC-NEXT: [[C:%.*]] = icmp eq i32 [[LGS1]], 421331; CGSCC-NEXT: store i32 13, ptr [[P]], align 41332; CGSCC-NEXT: call void @llvm.assume(i1 noundef [[C]]) #[[ATTR8]]1333; CGSCC-NEXT: [[LGS2:%.*]] = load i32, ptr @Gstatic_int2, align 41334; CGSCC-NEXT: store i32 17, ptr @Gstatic_int2, align 41335; CGSCC-NEXT: ret i32 [[LGS2]]1336;1337 %lgs1 = load i32, ptr @Gstatic_int21338 %c = icmp eq i32 %lgs1, 421339 store i32 13, ptr %p, align 41340 call void @llvm.assume(i1 %c)1341 %lgs2 = load i32, ptr @Gstatic_int21342 store i32 17, ptr @Gstatic_int2, align 41343 ret i32 %lgs21344}1345 1346define void @assume_write_globals() {1347;1348; TUNIT: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(write)1349; TUNIT-LABEL: define {{[^@]+}}@assume_write_globals1350; TUNIT-SAME: () #[[ATTR6:[0-9]+]] {1351; TUNIT-NEXT: store i32 42, ptr @Gstatic_int1, align 41352; TUNIT-NEXT: store i32 42, ptr @Gstatic_int2, align 41353; TUNIT-NEXT: ret void1354;1355; CGSCC: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(write)1356; CGSCC-LABEL: define {{[^@]+}}@assume_write_globals1357; CGSCC-SAME: () #[[ATTR7:[0-9]+]] {1358; CGSCC-NEXT: store i32 42, ptr @Gstatic_int1, align 41359; CGSCC-NEXT: store i32 42, ptr @Gstatic_int2, align 41360; CGSCC-NEXT: ret void1361;1362 store i32 42, ptr @Gstatic_int1, align 41363 store i32 42, ptr @Gstatic_int2, align 41364 ret void1365}1366 1367;.1368; TUNIT: attributes #[[ATTR0:[0-9]+]] = { nocallback nofree nosync nounwind willreturn memory(inaccessiblemem: write) }1369; TUNIT: attributes #[[ATTR1]] = { mustprogress nofree norecurse nosync nounwind willreturn memory(argmem: read) }1370; TUNIT: attributes #[[ATTR2]] = { norecurse }1371; TUNIT: attributes #[[ATTR3]] = { mustprogress nofree norecurse nosync nounwind willreturn memory(inaccessiblemem: write) }1372; TUNIT: attributes #[[ATTR4]] = { mustprogress nofree norecurse nosync nounwind willreturn memory(inaccessiblemem: readwrite) }1373; TUNIT: attributes #[[ATTR5]] = { mustprogress nofree norecurse nosync nounwind willreturn }1374; TUNIT: attributes #[[ATTR6]] = { mustprogress nofree norecurse nosync nounwind willreturn memory(write) }1375; TUNIT: attributes #[[ATTR7]] = { nofree willreturn memory(write) }1376; TUNIT: attributes #[[ATTR8]] = { nofree nosync nounwind willreturn memory(read) }1377; TUNIT: attributes #[[ATTR9]] = { nofree willreturn }1378;.1379; CGSCC: attributes #[[ATTR0:[0-9]+]] = { nocallback nofree nosync nounwind willreturn memory(inaccessiblemem: write) }1380; CGSCC: attributes #[[ATTR1]] = { mustprogress nofree norecurse nosync nounwind willreturn memory(argmem: read) }1381; CGSCC: attributes #[[ATTR2]] = { norecurse }1382; CGSCC: attributes #[[ATTR3]] = { mustprogress nofree norecurse nosync nounwind willreturn memory(inaccessiblemem: write) }1383; CGSCC: attributes #[[ATTR4]] = { mustprogress nofree norecurse nosync nounwind willreturn memory(inaccessiblemem: readwrite) }1384; CGSCC: attributes #[[ATTR5]] = { mustprogress nofree nosync nounwind willreturn memory(inaccessiblemem: readwrite) }1385; CGSCC: attributes #[[ATTR6]] = { mustprogress nofree norecurse nosync nounwind willreturn }1386; CGSCC: attributes #[[ATTR7]] = { mustprogress nofree norecurse nosync nounwind willreturn memory(write) }1387; CGSCC: attributes #[[ATTR8]] = { nofree willreturn memory(write) }1388; CGSCC: attributes #[[ATTR9]] = { nofree willreturn memory(read) }1389; CGSCC: attributes #[[ATTR10]] = { nofree willreturn }1390;.1391