1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --function-signature --check-attributes --check-globals 2; RUN: opt -aa-pipeline=basic-aa -passes=attributor -attributor-manifest-internal -attributor-annotate-decl-cs -S < %s | FileCheck %s --check-prefixes=CHECK,TUNIT 3; RUN: opt -aa-pipeline=basic-aa -passes=attributor-cgscc -attributor-manifest-internal -attributor-annotate-decl-cs -S < %s | FileCheck %s --check-prefixes=CHECK,CGSCC 4 5@Gstatic_int1 = internal global i32 zeroinitializer, align 4 6@Gstatic_int2 = internal global i32 zeroinitializer, align 4 7 8declare void @llvm.assume(i1) 9declare void @useI1p(ptr) 10declare void @unknown() 11 12;. 13; CHECK: @Gstatic_int1 = internal global i32 0, align 4 14; CHECK: @Gstatic_int2 = internal global i32 0, align 4 15;. 16define i1 @readI1p(ptr %p) { 17; CHECK: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(argmem: read) 18; CHECK-LABEL: define {{[^@]+}}@readI1p 19; CHECK-SAME: (ptr nofree noundef nonnull readonly captures(none) dereferenceable(1) [[P:%.*]]) #[[ATTR1:[0-9]+]] { 20; CHECK-NEXT: [[L:%.*]] = load i1, ptr [[P]], align 1 21; CHECK-NEXT: ret i1 [[L]] 22; 23 %l = load i1, ptr %p 24 ret i1 %l 25} 26 27define i1 @keep_assume_1c_nr() norecurse { 28; CHECK: Function Attrs: norecurse 29; CHECK-LABEL: define {{[^@]+}}@keep_assume_1c_nr 30; CHECK-SAME: () #[[ATTR2:[0-9]+]] { 31; CHECK-NEXT: [[STACK:%.*]] = alloca i1, align 1 32; CHECK-NEXT: store i1 true, ptr [[STACK]], align 1 33; CHECK-NEXT: call void @useI1p(ptr noundef nonnull dereferenceable(1) [[STACK]]) 34; CHECK-NEXT: [[L:%.*]] = load i1, ptr [[STACK]], align 1 35; CHECK-NEXT: call void @llvm.assume(i1 noundef [[L]]) 36; CHECK-NEXT: ret i1 [[L]] 37; 38 %stack = alloca i1 39 store i1 true, ptr %stack 40 call void @useI1p(ptr %stack) 41 %l = load i1, ptr %stack 42 call void @llvm.assume(i1 %l) 43 ret i1 %l 44} 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_nr 49; TUNIT-SAME: () #[[ATTR3:[0-9]+]] { 50; TUNIT-NEXT: call void @llvm.assume(i1 noundef true) #[[ATTR7:[0-9]+]] 51; TUNIT-NEXT: ret i1 true 52; 53; CGSCC: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(inaccessiblemem: write) 54; CGSCC-LABEL: define {{[^@]+}}@drop_assume_1c_nr 55; CGSCC-SAME: () #[[ATTR3:[0-9]+]] { 56; CGSCC-NEXT: call void @llvm.assume(i1 noundef true) #[[ATTR8:[0-9]+]] 57; CGSCC-NEXT: ret i1 true 58; 59 %stack = alloca i1 60 store i1 true, ptr %stack 61 %l = load i1, ptr %stack 62 call void @llvm.assume(i1 %l) 63 ret i1 %l 64} 65 66define i1 @keep_assume_2c_nr() norecurse { 67; CHECK: Function Attrs: norecurse 68; CHECK-LABEL: define {{[^@]+}}@keep_assume_2c_nr 69; CHECK-SAME: () #[[ATTR2]] { 70; CHECK-NEXT: [[STACK:%.*]] = alloca i1, align 1 71; CHECK-NEXT: store i1 true, ptr [[STACK]], align 1 72; CHECK-NEXT: call void @useI1p(ptr noundef nonnull dereferenceable(1) [[STACK]]) 73; CHECK-NEXT: [[L1:%.*]] = load i1, ptr [[STACK]], align 1 74; CHECK-NEXT: call void @llvm.assume(i1 noundef [[L1]]) 75; CHECK-NEXT: call void @unknown() 76; CHECK-NEXT: [[L2:%.*]] = load i1, ptr [[STACK]], align 1 77; CHECK-NEXT: ret i1 [[L2]] 78; 79 %stack = alloca i1 80 store i1 true, ptr %stack 81 call void @useI1p(ptr %stack) 82 %l1 = load i1, ptr %stack 83 call void @llvm.assume(i1 %l1) 84 call void @unknown() 85 %l2 = load i1, ptr %stack 86 ret i1 %l2 87} 88 89define i1 @keep_assume_3c_nr() norecurse { 90; 91; TUNIT: Function Attrs: norecurse 92; TUNIT-LABEL: define {{[^@]+}}@keep_assume_3c_nr 93; TUNIT-SAME: () #[[ATTR2]] { 94; TUNIT-NEXT: [[STACK:%.*]] = alloca i1, align 1 95; TUNIT-NEXT: store i1 true, ptr [[STACK]], align 1 96; TUNIT-NEXT: [[L:%.*]] = load i1, ptr [[STACK]], align 1 97; 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: norecurse 102; CGSCC-LABEL: define {{[^@]+}}@keep_assume_3c_nr 103; CGSCC-SAME: () #[[ATTR2]] { 104; CGSCC-NEXT: [[STACK:%.*]] = alloca i1, align 1 105; CGSCC-NEXT: store i1 true, ptr [[STACK]], align 1 106; CGSCC-NEXT: [[L:%.*]] = load i1, ptr [[STACK]], align 1 107; 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 i1 112 store i1 true, ptr %stack 113 %l = load i1, ptr %stack 114 call void @llvm.assume(i1 %l) 115 call void @useI1p(ptr %stack) 116 ret i1 %l 117} 118define i1 @keep_assume_4c_nr() norecurse { 119; 120; TUNIT: Function Attrs: norecurse 121; TUNIT-LABEL: define {{[^@]+}}@keep_assume_4c_nr 122; TUNIT-SAME: () #[[ATTR2]] { 123; TUNIT-NEXT: [[STACK:%.*]] = alloca i1, align 1 124; TUNIT-NEXT: store i1 true, ptr [[STACK]], align 1 125; 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 true 128; 129; CGSCC: Function Attrs: norecurse 130; CGSCC-LABEL: define {{[^@]+}}@keep_assume_4c_nr 131; CGSCC-SAME: () #[[ATTR2]] { 132; CGSCC-NEXT: [[STACK:%.*]] = alloca i1, align 1 133; CGSCC-NEXT: store i1 true, ptr [[STACK]], align 1 134; 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 true 137; 138 %stack = alloca i1 139 store i1 true, ptr %stack 140 %l4 = load i1, ptr %stack 141 call void @llvm.assume(i1 %l4) 142 call void @useI1p(ptr nocapture %stack) 143 ret i1 %l4 144} 145 146define i1 @keep_assume_1_nr(i1 %arg) norecurse { 147; CHECK: Function Attrs: norecurse 148; CHECK-LABEL: define {{[^@]+}}@keep_assume_1_nr 149; CHECK-SAME: (i1 [[ARG:%.*]]) #[[ATTR2]] { 150; CHECK-NEXT: [[STACK:%.*]] = alloca i1, align 1 151; CHECK-NEXT: store i1 [[ARG]], ptr [[STACK]], align 1 152; CHECK-NEXT: call void @useI1p(ptr noundef nonnull dereferenceable(1) [[STACK]]) 153; CHECK-NEXT: [[L:%.*]] = load i1, ptr [[STACK]], align 1 154; CHECK-NEXT: call void @llvm.assume(i1 noundef [[L]]) 155; CHECK-NEXT: ret i1 [[L]] 156; 157 %stack = alloca i1 158 store i1 %arg, ptr %stack 159 call void @useI1p(ptr %stack) 160 %l = load i1, ptr %stack 161 call void @llvm.assume(i1 %l) 162 ret i1 %l 163} 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_nr 168; TUNIT-SAME: (i1 returned [[ARG:%.*]]) #[[ATTR4:[0-9]+]] { 169; TUNIT-NEXT: [[STACK:%.*]] = alloca i1, align 1 170; TUNIT-NEXT: store i1 [[ARG]], ptr [[STACK]], align 1 171; 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_nr 176; CGSCC-SAME: (i1 returned [[ARG:%.*]]) #[[ATTR4:[0-9]+]] { 177; CGSCC-NEXT: [[STACK:%.*]] = alloca i1, align 1 178; CGSCC-NEXT: store i1 [[ARG]], ptr [[STACK]], align 1 179; CGSCC-NEXT: call void @llvm.assume(i1 noundef [[ARG]]) #[[ATTR8]] 180; CGSCC-NEXT: ret i1 [[ARG]] 181; 182 %stack = alloca i1 183 store i1 %arg, ptr %stack 184 %l = load i1, ptr %stack 185 call void @llvm.assume(i1 %l) 186 ret i1 %l 187} 188 189define i1 @keep_assume_2_nr(i1 %arg) norecurse { 190; CHECK: Function Attrs: norecurse 191; CHECK-LABEL: define {{[^@]+}}@keep_assume_2_nr 192; CHECK-SAME: (i1 [[ARG:%.*]]) #[[ATTR2]] { 193; CHECK-NEXT: [[STACK:%.*]] = alloca i1, align 1 194; CHECK-NEXT: store i1 [[ARG]], ptr [[STACK]], align 1 195; CHECK-NEXT: call void @useI1p(ptr noundef nonnull dereferenceable(1) [[STACK]]) 196; CHECK-NEXT: [[L1:%.*]] = load i1, ptr [[STACK]], align 1 197; CHECK-NEXT: call void @llvm.assume(i1 noundef [[L1]]) 198; CHECK-NEXT: call void @unknown() 199; CHECK-NEXT: [[L2:%.*]] = load i1, ptr [[STACK]], align 1 200; CHECK-NEXT: ret i1 [[L2]] 201; 202 %stack = alloca i1 203 store i1 %arg, ptr %stack 204 call void @useI1p(ptr %stack) 205 %l1 = load i1, ptr %stack 206 call void @llvm.assume(i1 %l1) 207 call void @unknown() 208 %l2 = load i1, ptr %stack 209 ret i1 %l2 210} 211 212define i1 @keep_assume_3_nr(i1 %arg) norecurse { 213; 214; TUNIT: Function Attrs: norecurse 215; TUNIT-LABEL: define {{[^@]+}}@keep_assume_3_nr 216; TUNIT-SAME: (i1 [[ARG:%.*]]) #[[ATTR2]] { 217; TUNIT-NEXT: [[STACK:%.*]] = alloca i1, align 1 218; TUNIT-NEXT: store i1 [[ARG]], ptr [[STACK]], align 1 219; TUNIT-NEXT: [[L:%.*]] = load i1, ptr [[STACK]], align 1 220; 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: norecurse 225; CGSCC-LABEL: define {{[^@]+}}@keep_assume_3_nr 226; CGSCC-SAME: (i1 [[ARG:%.*]]) #[[ATTR2]] { 227; CGSCC-NEXT: [[STACK:%.*]] = alloca i1, align 1 228; CGSCC-NEXT: store i1 [[ARG]], ptr [[STACK]], align 1 229; CGSCC-NEXT: [[L:%.*]] = load i1, ptr [[STACK]], align 1 230; 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 i1 235 store i1 %arg, ptr %stack 236 %l = load i1, ptr %stack 237 call void @llvm.assume(i1 %l) 238 call void @useI1p(ptr %stack) 239 ret i1 %l 240} 241 242define i1 @keep_assume_4_nr(i1 %arg) norecurse { 243; 244; TUNIT: Function Attrs: norecurse 245; TUNIT-LABEL: define {{[^@]+}}@keep_assume_4_nr 246; TUNIT-SAME: (i1 returned [[ARG:%.*]]) #[[ATTR2]] { 247; TUNIT-NEXT: [[STACK:%.*]] = alloca i1, align 1 248; TUNIT-NEXT: store i1 [[ARG]], ptr [[STACK]], align 1 249; 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: norecurse 254; CGSCC-LABEL: define {{[^@]+}}@keep_assume_4_nr 255; CGSCC-SAME: (i1 returned [[ARG:%.*]]) #[[ATTR2]] { 256; CGSCC-NEXT: [[STACK:%.*]] = alloca i1, align 1 257; CGSCC-NEXT: store i1 [[ARG]], ptr [[STACK]], align 1 258; 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 i1 263 store i1 %arg, ptr %stack 264 %l = load i1, ptr %stack 265 call void @llvm.assume(i1 %l) 266 call void @useI1p(ptr nocapture %stack) 267 ret i1 %l 268} 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_nr 273; TUNIT-SAME: (i1 returned [[ARG:%.*]], i1 noundef [[COND:%.*]]) #[[ATTR4]] { 274; TUNIT-NEXT: [[STACK:%.*]] = alloca i1, align 1 275; TUNIT-NEXT: store i1 [[ARG]], ptr [[STACK]], align 1 276; 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_nr 287; CGSCC-SAME: (i1 returned [[ARG:%.*]], i1 noundef [[COND:%.*]]) #[[ATTR4]] { 288; CGSCC-NEXT: [[STACK:%.*]] = alloca i1, align 1 289; CGSCC-NEXT: store i1 [[ARG]], ptr [[STACK]], align 1 290; 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 i1 300 store i1 %arg, ptr %stack 301 %l = load i1, ptr %stack 302 call void @llvm.assume(i1 %l) 303 br i1 %cond, label %t, label %f 304t: 305 store i1 true, ptr %stack 306 br label %m 307f: 308 store i1 false, ptr %stack 309 br label %m 310m: 311 ret i1 %l 312} 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_nr 317; 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 void 325; 326 %stack = alloca i1 327 store i1 %arg, ptr %stack 328 %l = load i1, ptr %stack 329 call void @llvm.assume(i1 %l) 330 br i1 %cond, label %t, label %f 331t: 332 store i1 true, ptr %stack 333 br label %m 334f: 335 store i1 false, ptr %stack 336 br label %m 337m: 338 ret void 339} 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_nr 344; TUNIT-SAME: (i1 [[ARG:%.*]], i1 noundef [[COND:%.*]]) #[[ATTR4]] { 345; TUNIT-NEXT: [[STACK:%.*]] = alloca i1, align 1 346; TUNIT-NEXT: br i1 [[COND]], label [[T:%.*]], label [[F:%.*]] 347; TUNIT: t: 348; TUNIT-NEXT: store i1 true, ptr [[STACK]], align 1 349; TUNIT-NEXT: br label [[M:%.*]] 350; TUNIT: f: 351; TUNIT-NEXT: store i1 false, ptr [[STACK]], align 1 352; TUNIT-NEXT: br label [[M]] 353; TUNIT: m: 354; TUNIT-NEXT: [[L:%.*]] = load i1, ptr [[STACK]], align 1 355; 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_nr 360; CGSCC-SAME: (i1 [[ARG:%.*]], i1 noundef [[COND:%.*]]) #[[ATTR4]] { 361; CGSCC-NEXT: [[STACK:%.*]] = alloca i1, align 1 362; CGSCC-NEXT: br i1 [[COND]], label [[T:%.*]], label [[F:%.*]] 363; CGSCC: t: 364; CGSCC-NEXT: store i1 true, ptr [[STACK]], align 1 365; CGSCC-NEXT: br label [[M:%.*]] 366; CGSCC: f: 367; CGSCC-NEXT: store i1 false, ptr [[STACK]], align 1 368; CGSCC-NEXT: br label [[M]] 369; CGSCC: m: 370; CGSCC-NEXT: [[L:%.*]] = load i1, ptr [[STACK]], align 1 371; CGSCC-NEXT: call void @llvm.assume(i1 noundef [[L]]) #[[ATTR8]] 372; CGSCC-NEXT: ret i1 [[L]] 373; 374 %stack = alloca i1 375 store i1 %arg, ptr %stack 376 br i1 %cond, label %t, label %f 377t: 378 store i1 true, ptr %stack 379 br label %m 380f: 381 store i1 false, ptr %stack 382 br label %m 383m: 384 %l = load i1, ptr %stack 385 call void @llvm.assume(i1 %l) 386 ret i1 %l 387} 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_nr 392; CHECK-SAME: (i1 [[ARG:%.*]], i1 noundef [[COND:%.*]]) #[[ATTR4]] { 393; CHECK-NEXT: [[STACK:%.*]] = alloca i1, align 1 394; 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 1 401; CHECK-NEXT: ret void 402; 403 %stack = alloca i1 404 store i1 %arg, ptr %stack 405 br i1 %cond, label %t, label %f 406t: 407 store i1 true, ptr %stack 408 br label %m 409f: 410 store i1 false, ptr %stack 411 br label %m 412m: 413 %l = load i1, ptr %stack 414 call void @llvm.assume(i1 %l) 415 ret void 416} 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_nr 421; TUNIT-SAME: (i1 [[ARG:%.*]], i1 noundef [[COND:%.*]]) #[[ATTR4]] { 422; TUNIT-NEXT: [[STACK:%.*]] = alloca i1, align 1 423; TUNIT-NEXT: br i1 [[COND]], label [[T:%.*]], label [[F:%.*]] 424; TUNIT: t: 425; TUNIT-NEXT: store i1 true, ptr [[STACK]], align 1 426; TUNIT-NEXT: br label [[M:%.*]] 427; TUNIT: f: 428; TUNIT-NEXT: store i1 false, ptr [[STACK]], align 1 429; 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_nr 436; CGSCC-SAME: (i1 [[ARG:%.*]], i1 noundef [[COND:%.*]]) #[[ATTR4]] { 437; CGSCC-NEXT: [[STACK:%.*]] = alloca i1, align 1 438; CGSCC-NEXT: store i1 [[ARG]], ptr [[STACK]], align 1 439; CGSCC-NEXT: [[L:%.*]] = load i1, ptr [[STACK]], align 1 440; 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 1 444; CGSCC-NEXT: br label [[M:%.*]] 445; CGSCC: f: 446; CGSCC-NEXT: store i1 false, ptr [[STACK]], align 1 447; 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 i1 453 store i1 %arg, ptr %stack 454 %l = load i1, ptr %stack 455 call void @llvm.assume(i1 %l) 456 br i1 %cond, label %t, label %f 457t: 458 store i1 true, ptr %stack 459 br label %m 460f: 461 store i1 false, ptr %stack 462 br label %m 463m: 464 %r = call i1 @readI1p(ptr %stack) 465 ret i1 %r 466} 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_nr 471; TUNIT-SAME: (i1 [[ARG:%.*]], i1 noundef [[COND:%.*]]) #[[ATTR4]] { 472; TUNIT-NEXT: [[STACK:%.*]] = alloca i1, align 1 473; TUNIT-NEXT: br i1 [[COND]], label [[T:%.*]], label [[F:%.*]] 474; TUNIT: t: 475; TUNIT-NEXT: store i1 true, ptr [[STACK]], align 1 476; TUNIT-NEXT: br label [[M:%.*]] 477; TUNIT: f: 478; TUNIT-NEXT: store i1 false, ptr [[STACK]], align 1 479; TUNIT-NEXT: br label [[M]] 480; TUNIT: m: 481; TUNIT-NEXT: [[L:%.*]] = load i1, ptr [[STACK]], align 1 482; 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_nr 488; CGSCC-SAME: (i1 [[ARG:%.*]], i1 noundef [[COND:%.*]]) #[[ATTR4]] { 489; CGSCC-NEXT: [[STACK:%.*]] = alloca i1, align 1 490; CGSCC-NEXT: store i1 [[ARG]], ptr [[STACK]], align 1 491; CGSCC-NEXT: br i1 [[COND]], label [[T:%.*]], label [[F:%.*]] 492; CGSCC: t: 493; CGSCC-NEXT: store i1 true, ptr [[STACK]], align 1 494; CGSCC-NEXT: br label [[M:%.*]] 495; CGSCC: f: 496; CGSCC-NEXT: store i1 false, ptr [[STACK]], align 1 497; CGSCC-NEXT: br label [[M]] 498; CGSCC: m: 499; CGSCC-NEXT: [[L:%.*]] = load i1, ptr [[STACK]], align 1 500; 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 i1 505 store i1 %arg, ptr %stack 506 br i1 %cond, label %t, label %f 507t: 508 store i1 true, ptr %stack 509 br label %m 510f: 511 store i1 false, ptr %stack 512 br label %m 513m: 514 %l = load i1, ptr %stack 515 call void @llvm.assume(i1 %l) 516 %r = call i1 @readI1p(ptr %stack) 517 ret i1 %r 518} 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_nr 523; TUNIT-SAME: (i1 [[ARG:%.*]], i1 noundef [[COND:%.*]]) #[[ATTR4]] { 524; TUNIT-NEXT: [[STACK:%.*]] = alloca i1, align 1 525; TUNIT-NEXT: br i1 [[COND]], label [[T:%.*]], label [[F:%.*]] 526; TUNIT: t: 527; TUNIT-NEXT: store i1 true, ptr [[STACK]], align 1 528; TUNIT-NEXT: [[L2:%.*]] = load i1, ptr [[STACK]], align 1 529; 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 1 533; TUNIT-NEXT: [[L3:%.*]] = load i1, ptr [[STACK]], align 1 534; 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 1 538; 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_nr 544; CGSCC-SAME: (i1 [[ARG:%.*]], i1 noundef [[COND:%.*]]) #[[ATTR4]] { 545; CGSCC-NEXT: [[STACK:%.*]] = alloca i1, align 1 546; CGSCC-NEXT: store i1 [[ARG]], ptr [[STACK]], align 1 547; CGSCC-NEXT: [[L1:%.*]] = load i1, ptr [[STACK]], align 1 548; 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 1 552; CGSCC-NEXT: [[L2:%.*]] = load i1, ptr [[STACK]], align 1 553; 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 1 557; CGSCC-NEXT: [[L3:%.*]] = load i1, ptr [[STACK]], align 1 558; 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 1 562; 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 i1 567 store i1 %arg, ptr %stack 568 %l1 = load i1, ptr %stack 569 call void @llvm.assume(i1 %l1) 570 br i1 %cond, label %t, label %f 571t: 572 store i1 true, ptr %stack 573 %l2 = load i1, ptr %stack 574 call void @llvm.assume(i1 %l2) 575 br label %m 576f: 577 store i1 false, ptr %stack 578 %l3 = load i1, ptr %stack 579 call void @llvm.assume(i1 %l3) 580 br label %m 581m: 582 %l4 = load i1, ptr %stack 583 call void @llvm.assume(i1 %l4) 584 %r = call i1 @readI1p(ptr %stack) 585 ret i1 %r 586} 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_nr 591; TUNIT-SAME: (i1 noundef [[COND:%.*]]) #[[ATTR4]] { 592; TUNIT-NEXT: [[STACK:%.*]] = alloca i1, align 1 593; 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 1 597; TUNIT-NEXT: [[L2:%.*]] = load i1, ptr [[STACK]], align 1 598; 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 1 602; TUNIT-NEXT: [[L3:%.*]] = load i1, ptr [[STACK]], align 1 603; 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 1 607; 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_nr 613; CGSCC-SAME: (i1 noundef [[COND:%.*]]) #[[ATTR4]] { 614; CGSCC-NEXT: [[STACK:%.*]] = alloca i1, align 1 615; CGSCC-NEXT: store i1 true, ptr [[STACK]], align 1 616; CGSCC-NEXT: [[L1:%.*]] = load i1, ptr [[STACK]], align 1 617; 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 1 621; CGSCC-NEXT: [[L2:%.*]] = load i1, ptr [[STACK]], align 1 622; 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 1 626; CGSCC-NEXT: [[L3:%.*]] = load i1, ptr [[STACK]], align 1 627; 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 1 631; 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 i1 636 store i1 true, ptr %stack 637 %l1 = load i1, ptr %stack 638 call void @llvm.assume(i1 %l1) 639 br i1 %cond, label %t, label %f 640t: 641 store i1 true, ptr %stack 642 %l2 = load i1, ptr %stack 643 call void @llvm.assume(i1 %l2) 644 br label %m 645f: 646 store i1 false, ptr %stack 647 %l3 = load i1, ptr %stack 648 call void @llvm.assume(i1 %l3) 649 br label %m 650m: 651 %l4 = load i1, ptr %stack 652 call void @llvm.assume(i1 %l4) 653 %r = call i1 @readI1p(ptr %stack) 654 ret i1 %r 655} 656 657 658define i1 @keep_assume_1c() { 659; CHECK-LABEL: define {{[^@]+}}@keep_assume_1c() { 660; CHECK-NEXT: [[STACK:%.*]] = alloca i1, align 1 661; CHECK-NEXT: store i1 true, ptr [[STACK]], align 1 662; CHECK-NEXT: call void @useI1p(ptr noundef nonnull dereferenceable(1) [[STACK]]) 663; CHECK-NEXT: [[L:%.*]] = load i1, ptr [[STACK]], align 1 664; CHECK-NEXT: call void @llvm.assume(i1 noundef [[L]]) 665; CHECK-NEXT: ret i1 [[L]] 666; 667 %stack = alloca i1 668 store i1 true, ptr %stack 669 call void @useI1p(ptr %stack) 670 %l = load i1, ptr %stack 671 call void @llvm.assume(i1 %l) 672 ret i1 %l 673} 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_1c 678; TUNIT-SAME: () #[[ATTR3]] { 679; TUNIT-NEXT: call void @llvm.assume(i1 noundef true) #[[ATTR7]] 680; TUNIT-NEXT: ret i1 true 681; 682; CGSCC: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(inaccessiblemem: write) 683; CGSCC-LABEL: define {{[^@]+}}@drop_assume_1c 684; CGSCC-SAME: () #[[ATTR3]] { 685; CGSCC-NEXT: call void @llvm.assume(i1 noundef true) #[[ATTR8]] 686; CGSCC-NEXT: ret i1 true 687; 688 %stack = alloca i1 689 store i1 true, ptr %stack 690 %l = load i1, ptr %stack 691 call void @llvm.assume(i1 %l) 692 ret i1 %l 693} 694 695define i1 @keep_assume_2c() { 696; CHECK-LABEL: define {{[^@]+}}@keep_assume_2c() { 697; CHECK-NEXT: [[STACK:%.*]] = alloca i1, align 1 698; CHECK-NEXT: store i1 true, ptr [[STACK]], align 1 699; CHECK-NEXT: call void @useI1p(ptr noundef nonnull dereferenceable(1) [[STACK]]) 700; CHECK-NEXT: [[L1:%.*]] = load i1, ptr [[STACK]], align 1 701; CHECK-NEXT: call void @llvm.assume(i1 noundef [[L1]]) 702; CHECK-NEXT: call void @unknown() 703; CHECK-NEXT: [[L2:%.*]] = load i1, ptr [[STACK]], align 1 704; CHECK-NEXT: ret i1 [[L2]] 705; 706 %stack = alloca i1 707 store i1 true, ptr %stack 708 call void @useI1p(ptr %stack) 709 %l1 = load i1, ptr %stack 710 call void @llvm.assume(i1 %l1) 711 call void @unknown() 712 %l2 = load i1, ptr %stack 713 ret i1 %l2 714} 715 716define i1 @keep_assume_3c() { 717; 718; TUNIT-LABEL: define {{[^@]+}}@keep_assume_3c() { 719; TUNIT-NEXT: [[STACK:%.*]] = alloca i1, align 1 720; TUNIT-NEXT: store i1 true, ptr [[STACK]], align 1 721; TUNIT-NEXT: [[L:%.*]] = load i1, ptr [[STACK]], align 1 722; 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 1 728; CGSCC-NEXT: store i1 true, ptr [[STACK]], align 1 729; CGSCC-NEXT: [[L:%.*]] = load i1, ptr [[STACK]], align 1 730; 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 i1 735 store i1 true, ptr %stack 736 %l = load i1, ptr %stack 737 call void @llvm.assume(i1 %l) 738 call void @useI1p(ptr %stack) 739 ret i1 %l 740} 741define i1 @keep_assume_4c() { 742; 743; TUNIT-LABEL: define {{[^@]+}}@keep_assume_4c() { 744; TUNIT-NEXT: [[STACK:%.*]] = alloca i1, align 1 745; TUNIT-NEXT: store i1 true, ptr [[STACK]], align 1 746; TUNIT-NEXT: [[L4:%.*]] = load i1, ptr [[STACK]], align 1 747; 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 1 753; CGSCC-NEXT: store i1 true, ptr [[STACK]], align 1 754; CGSCC-NEXT: [[L4:%.*]] = load i1, ptr [[STACK]], align 1 755; 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 i1 760 store i1 true, ptr %stack 761 %l4 = load i1, ptr %stack 762 call void @llvm.assume(i1 %l4) 763 call void @useI1p(ptr nocapture %stack) 764 ret i1 %l4 765} 766 767define i1 @keep_assume_1(i1 %arg) { 768; CHECK-LABEL: define {{[^@]+}}@keep_assume_1 769; CHECK-SAME: (i1 [[ARG:%.*]]) { 770; CHECK-NEXT: [[STACK:%.*]] = alloca i1, align 1 771; CHECK-NEXT: store i1 [[ARG]], ptr [[STACK]], align 1 772; CHECK-NEXT: call void @useI1p(ptr noundef nonnull dereferenceable(1) [[STACK]]) 773; CHECK-NEXT: [[L:%.*]] = load i1, ptr [[STACK]], align 1 774; CHECK-NEXT: call void @llvm.assume(i1 noundef [[L]]) 775; CHECK-NEXT: ret i1 [[L]] 776; 777 %stack = alloca i1 778 store i1 %arg, ptr %stack 779 call void @useI1p(ptr %stack) 780 %l = load i1, ptr %stack 781 call void @llvm.assume(i1 %l) 782 ret i1 %l 783} 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_1 788; TUNIT-SAME: (i1 returned [[ARG:%.*]]) #[[ATTR4]] { 789; TUNIT-NEXT: [[STACK:%.*]] = alloca i1, align 1 790; TUNIT-NEXT: store i1 [[ARG]], ptr [[STACK]], align 1 791; 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_1 796; CGSCC-SAME: (i1 returned [[ARG:%.*]]) #[[ATTR4]] { 797; CGSCC-NEXT: [[STACK:%.*]] = alloca i1, align 1 798; CGSCC-NEXT: store i1 [[ARG]], ptr [[STACK]], align 1 799; CGSCC-NEXT: call void @llvm.assume(i1 noundef [[ARG]]) #[[ATTR8]] 800; CGSCC-NEXT: ret i1 [[ARG]] 801; 802 %stack = alloca i1 803 store i1 %arg, ptr %stack 804 %l = load i1, ptr %stack 805 call void @llvm.assume(i1 %l) 806 ret i1 %l 807} 808 809define i1 @keep_assume_2(i1 %arg) { 810; CHECK-LABEL: define {{[^@]+}}@keep_assume_2 811; CHECK-SAME: (i1 [[ARG:%.*]]) { 812; CHECK-NEXT: [[STACK:%.*]] = alloca i1, align 1 813; CHECK-NEXT: store i1 [[ARG]], ptr [[STACK]], align 1 814; CHECK-NEXT: call void @useI1p(ptr noundef nonnull dereferenceable(1) [[STACK]]) 815; CHECK-NEXT: [[L1:%.*]] = load i1, ptr [[STACK]], align 1 816; CHECK-NEXT: call void @llvm.assume(i1 noundef [[L1]]) 817; CHECK-NEXT: call void @unknown() 818; CHECK-NEXT: [[L2:%.*]] = load i1, ptr [[STACK]], align 1 819; CHECK-NEXT: ret i1 [[L2]] 820; 821 %stack = alloca i1 822 store i1 %arg, ptr %stack 823 call void @useI1p(ptr %stack) 824 %l1 = load i1, ptr %stack 825 call void @llvm.assume(i1 %l1) 826 call void @unknown() 827 %l2 = load i1, ptr %stack 828 ret i1 %l2 829} 830 831define i1 @keep_assume_3(i1 %arg) { 832; 833; TUNIT-LABEL: define {{[^@]+}}@keep_assume_3 834; TUNIT-SAME: (i1 [[ARG:%.*]]) { 835; TUNIT-NEXT: [[STACK:%.*]] = alloca i1, align 1 836; TUNIT-NEXT: store i1 [[ARG]], ptr [[STACK]], align 1 837; TUNIT-NEXT: [[L:%.*]] = load i1, ptr [[STACK]], align 1 838; 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_3 843; CGSCC-SAME: (i1 [[ARG:%.*]]) { 844; CGSCC-NEXT: [[STACK:%.*]] = alloca i1, align 1 845; CGSCC-NEXT: store i1 [[ARG]], ptr [[STACK]], align 1 846; CGSCC-NEXT: [[L:%.*]] = load i1, ptr [[STACK]], align 1 847; 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 i1 852 store i1 %arg, ptr %stack 853 %l = load i1, ptr %stack 854 call void @llvm.assume(i1 %l) 855 call void @useI1p(ptr %stack) 856 ret i1 %l 857} 858 859define i1 @keep_assume_4(i1 %arg) { 860; 861; TUNIT-LABEL: define {{[^@]+}}@keep_assume_4 862; TUNIT-SAME: (i1 [[ARG:%.*]]) { 863; TUNIT-NEXT: [[STACK:%.*]] = alloca i1, align 1 864; TUNIT-NEXT: store i1 [[ARG]], ptr [[STACK]], align 1 865; TUNIT-NEXT: [[L:%.*]] = load i1, ptr [[STACK]], align 1 866; 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_4 871; CGSCC-SAME: (i1 [[ARG:%.*]]) { 872; CGSCC-NEXT: [[STACK:%.*]] = alloca i1, align 1 873; CGSCC-NEXT: store i1 [[ARG]], ptr [[STACK]], align 1 874; CGSCC-NEXT: [[L:%.*]] = load i1, ptr [[STACK]], align 1 875; 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 i1 880 store i1 %arg, ptr %stack 881 %l = load i1, ptr %stack 882 call void @llvm.assume(i1 %l) 883 call void @useI1p(ptr nocapture %stack) 884 ret i1 %l 885} 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_1 890; TUNIT-SAME: (i1 returned [[ARG:%.*]], i1 noundef [[COND:%.*]]) #[[ATTR4]] { 891; TUNIT-NEXT: [[STACK:%.*]] = alloca i1, align 1 892; TUNIT-NEXT: store i1 [[ARG]], ptr [[STACK]], align 1 893; 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_1 904; CGSCC-SAME: (i1 returned [[ARG:%.*]], i1 noundef [[COND:%.*]]) #[[ATTR4]] { 905; CGSCC-NEXT: [[STACK:%.*]] = alloca i1, align 1 906; CGSCC-NEXT: store i1 [[ARG]], ptr [[STACK]], align 1 907; 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 i1 917 store i1 %arg, ptr %stack 918 %l = load i1, ptr %stack 919 call void @llvm.assume(i1 %l) 920 br i1 %cond, label %t, label %f 921t: 922 store i1 true, ptr %stack 923 br label %m 924f: 925 store i1 false, ptr %stack 926 br label %m 927m: 928 ret i1 %l 929} 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_1b 934; 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 void 942; 943 %stack = alloca i1 944 store i1 %arg, ptr %stack 945 %l = load i1, ptr %stack 946 call void @llvm.assume(i1 %l) 947 br i1 %cond, label %t, label %f 948t: 949 store i1 true, ptr %stack 950 br label %m 951f: 952 store i1 false, ptr %stack 953 br label %m 954m: 955 ret void 956} 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_2 961; TUNIT-SAME: (i1 [[ARG:%.*]], i1 noundef [[COND:%.*]]) #[[ATTR4]] { 962; TUNIT-NEXT: [[STACK:%.*]] = alloca i1, align 1 963; TUNIT-NEXT: br i1 [[COND]], label [[T:%.*]], label [[F:%.*]] 964; TUNIT: t: 965; TUNIT-NEXT: store i1 true, ptr [[STACK]], align 1 966; TUNIT-NEXT: br label [[M:%.*]] 967; TUNIT: f: 968; TUNIT-NEXT: store i1 false, ptr [[STACK]], align 1 969; TUNIT-NEXT: br label [[M]] 970; TUNIT: m: 971; TUNIT-NEXT: [[L:%.*]] = load i1, ptr [[STACK]], align 1 972; 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_2 977; CGSCC-SAME: (i1 [[ARG:%.*]], i1 noundef [[COND:%.*]]) #[[ATTR4]] { 978; CGSCC-NEXT: [[STACK:%.*]] = alloca i1, align 1 979; CGSCC-NEXT: br i1 [[COND]], label [[T:%.*]], label [[F:%.*]] 980; CGSCC: t: 981; CGSCC-NEXT: store i1 true, ptr [[STACK]], align 1 982; CGSCC-NEXT: br label [[M:%.*]] 983; CGSCC: f: 984; CGSCC-NEXT: store i1 false, ptr [[STACK]], align 1 985; CGSCC-NEXT: br label [[M]] 986; CGSCC: m: 987; CGSCC-NEXT: [[L:%.*]] = load i1, ptr [[STACK]], align 1 988; CGSCC-NEXT: call void @llvm.assume(i1 noundef [[L]]) #[[ATTR8]] 989; CGSCC-NEXT: ret i1 [[L]] 990; 991 %stack = alloca i1 992 store i1 %arg, ptr %stack 993 br i1 %cond, label %t, label %f 994t: 995 store i1 true, ptr %stack 996 br label %m 997f: 998 store i1 false, ptr %stack 999 br label %m 1000m: 1001 %l = load i1, ptr %stack 1002 call void @llvm.assume(i1 %l) 1003 ret i1 %l 1004} 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_2b 1009; CHECK-SAME: (i1 [[ARG:%.*]], i1 noundef [[COND:%.*]]) #[[ATTR4]] { 1010; CHECK-NEXT: [[STACK:%.*]] = alloca i1, align 1 1011; 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 1 1018; CHECK-NEXT: ret void 1019; 1020 %stack = alloca i1 1021 store i1 %arg, ptr %stack 1022 br i1 %cond, label %t, label %f 1023t: 1024 store i1 true, ptr %stack 1025 br label %m 1026f: 1027 store i1 false, ptr %stack 1028 br label %m 1029m: 1030 %l = load i1, ptr %stack 1031 call void @llvm.assume(i1 %l) 1032 ret void 1033} 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_3 1038; TUNIT-SAME: (i1 [[ARG:%.*]], i1 noundef [[COND:%.*]]) #[[ATTR4]] { 1039; TUNIT-NEXT: [[STACK:%.*]] = alloca i1, align 1 1040; TUNIT-NEXT: br i1 [[COND]], label [[T:%.*]], label [[F:%.*]] 1041; TUNIT: t: 1042; TUNIT-NEXT: store i1 true, ptr [[STACK]], align 1 1043; TUNIT-NEXT: br label [[M:%.*]] 1044; TUNIT: f: 1045; TUNIT-NEXT: store i1 false, ptr [[STACK]], align 1 1046; 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_3 1053; CGSCC-SAME: (i1 [[ARG:%.*]], i1 noundef [[COND:%.*]]) #[[ATTR5:[0-9]+]] { 1054; CGSCC-NEXT: [[STACK:%.*]] = alloca i1, align 1 1055; CGSCC-NEXT: store i1 [[ARG]], ptr [[STACK]], align 1 1056; CGSCC-NEXT: [[L:%.*]] = load i1, ptr [[STACK]], align 1 1057; 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 1 1061; CGSCC-NEXT: br label [[M:%.*]] 1062; CGSCC: f: 1063; CGSCC-NEXT: store i1 false, ptr [[STACK]], align 1 1064; 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 i1 1070 store i1 %arg, ptr %stack 1071 %l = load i1, ptr %stack 1072 call void @llvm.assume(i1 %l) 1073 br i1 %cond, label %t, label %f 1074t: 1075 store i1 true, ptr %stack 1076 br label %m 1077f: 1078 store i1 false, ptr %stack 1079 br label %m 1080m: 1081 %r = call i1 @readI1p(ptr %stack) 1082 ret i1 %r 1083} 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_4 1088; TUNIT-SAME: (i1 [[ARG:%.*]], i1 noundef [[COND:%.*]]) #[[ATTR4]] { 1089; TUNIT-NEXT: [[STACK:%.*]] = alloca i1, align 1 1090; TUNIT-NEXT: br i1 [[COND]], label [[T:%.*]], label [[F:%.*]] 1091; TUNIT: t: 1092; TUNIT-NEXT: store i1 true, ptr [[STACK]], align 1 1093; TUNIT-NEXT: br label [[M:%.*]] 1094; TUNIT: f: 1095; TUNIT-NEXT: store i1 false, ptr [[STACK]], align 1 1096; TUNIT-NEXT: br label [[M]] 1097; TUNIT: m: 1098; TUNIT-NEXT: [[L:%.*]] = load i1, ptr [[STACK]], align 1 1099; 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_4 1105; CGSCC-SAME: (i1 [[ARG:%.*]], i1 noundef [[COND:%.*]]) #[[ATTR5]] { 1106; CGSCC-NEXT: [[STACK:%.*]] = alloca i1, align 1 1107; CGSCC-NEXT: store i1 [[ARG]], ptr [[STACK]], align 1 1108; CGSCC-NEXT: br i1 [[COND]], label [[T:%.*]], label [[F:%.*]] 1109; CGSCC: t: 1110; CGSCC-NEXT: store i1 true, ptr [[STACK]], align 1 1111; CGSCC-NEXT: br label [[M:%.*]] 1112; CGSCC: f: 1113; CGSCC-NEXT: store i1 false, ptr [[STACK]], align 1 1114; CGSCC-NEXT: br label [[M]] 1115; CGSCC: m: 1116; CGSCC-NEXT: [[L:%.*]] = load i1, ptr [[STACK]], align 1 1117; 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 i1 1122 store i1 %arg, ptr %stack 1123 br i1 %cond, label %t, label %f 1124t: 1125 store i1 true, ptr %stack 1126 br label %m 1127f: 1128 store i1 false, ptr %stack 1129 br label %m 1130m: 1131 %l = load i1, ptr %stack 1132 call void @llvm.assume(i1 %l) 1133 %r = call i1 @readI1p(ptr %stack) 1134 ret i1 %r 1135} 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_5 1140; TUNIT-SAME: (i1 [[ARG:%.*]], i1 noundef [[COND:%.*]]) #[[ATTR4]] { 1141; TUNIT-NEXT: [[STACK:%.*]] = alloca i1, align 1 1142; TUNIT-NEXT: br i1 [[COND]], label [[T:%.*]], label [[F:%.*]] 1143; TUNIT: t: 1144; TUNIT-NEXT: store i1 true, ptr [[STACK]], align 1 1145; TUNIT-NEXT: [[L2:%.*]] = load i1, ptr [[STACK]], align 1 1146; 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 1 1150; TUNIT-NEXT: [[L3:%.*]] = load i1, ptr [[STACK]], align 1 1151; 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 1 1155; 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_5 1161; CGSCC-SAME: (i1 [[ARG:%.*]], i1 noundef [[COND:%.*]]) #[[ATTR5]] { 1162; CGSCC-NEXT: [[STACK:%.*]] = alloca i1, align 1 1163; CGSCC-NEXT: store i1 [[ARG]], ptr [[STACK]], align 1 1164; CGSCC-NEXT: [[L1:%.*]] = load i1, ptr [[STACK]], align 1 1165; 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 1 1169; CGSCC-NEXT: [[L2:%.*]] = load i1, ptr [[STACK]], align 1 1170; 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 1 1174; CGSCC-NEXT: [[L3:%.*]] = load i1, ptr [[STACK]], align 1 1175; 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 1 1179; 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 i1 1184 store i1 %arg, ptr %stack 1185 %l1 = load i1, ptr %stack 1186 call void @llvm.assume(i1 %l1) 1187 br i1 %cond, label %t, label %f 1188t: 1189 store i1 true, ptr %stack 1190 %l2 = load i1, ptr %stack 1191 call void @llvm.assume(i1 %l2) 1192 br label %m 1193f: 1194 store i1 false, ptr %stack 1195 %l3 = load i1, ptr %stack 1196 call void @llvm.assume(i1 %l3) 1197 br label %m 1198m: 1199 %l4 = load i1, ptr %stack 1200 call void @llvm.assume(i1 %l4) 1201 %r = call i1 @readI1p(ptr %stack) 1202 ret i1 %r 1203} 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_5c 1208; TUNIT-SAME: (i1 noundef [[COND:%.*]]) #[[ATTR4]] { 1209; TUNIT-NEXT: [[STACK:%.*]] = alloca i1, align 1 1210; 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 1 1214; TUNIT-NEXT: [[L2:%.*]] = load i1, ptr [[STACK]], align 1 1215; 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 1 1219; TUNIT-NEXT: [[L3:%.*]] = load i1, ptr [[STACK]], align 1 1220; 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 1 1224; 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_5c 1230; CGSCC-SAME: (i1 noundef [[COND:%.*]]) #[[ATTR5]] { 1231; CGSCC-NEXT: [[STACK:%.*]] = alloca i1, align 1 1232; CGSCC-NEXT: store i1 true, ptr [[STACK]], align 1 1233; CGSCC-NEXT: [[L1:%.*]] = load i1, ptr [[STACK]], align 1 1234; 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 1 1238; CGSCC-NEXT: [[L2:%.*]] = load i1, ptr [[STACK]], align 1 1239; 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 1 1243; CGSCC-NEXT: [[L3:%.*]] = load i1, ptr [[STACK]], align 1 1244; 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 1 1248; 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 i1 1253 store i1 true, ptr %stack 1254 %l1 = load i1, ptr %stack 1255 call void @llvm.assume(i1 %l1) 1256 br i1 %cond, label %t, label %f 1257t: 1258 store i1 true, ptr %stack 1259 %l2 = load i1, ptr %stack 1260 call void @llvm.assume(i1 %l2) 1261 br label %m 1262f: 1263 store i1 false, ptr %stack 1264 %l3 = load i1, ptr %stack 1265 call void @llvm.assume(i1 %l3) 1266 br label %m 1267m: 1268 %l4 = load i1, ptr %stack 1269 call void @llvm.assume(i1 %l4) 1270 %r = call i1 @readI1p(ptr %stack) 1271 ret i1 %r 1272} 1273 1274define i32 @assume_read_global_good() { 1275; 1276; 1277; TUNIT: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn 1278; TUNIT-LABEL: define {{[^@]+}}@assume_read_global_good 1279; TUNIT-SAME: () #[[ATTR5:[0-9]+]] { 1280; TUNIT-NEXT: [[LGS1:%.*]] = load i32, ptr @Gstatic_int1, align 4 1281; TUNIT-NEXT: [[C:%.*]] = icmp eq i32 [[LGS1]], 42 1282; TUNIT-NEXT: call void @llvm.assume(i1 noundef [[C]]) #[[ATTR7]] 1283; TUNIT-NEXT: [[LGS2:%.*]] = load i32, ptr @Gstatic_int1, align 4 1284; TUNIT-NEXT: store i32 17, ptr @Gstatic_int1, align 4 1285; TUNIT-NEXT: [[LGS3:%.*]] = load i32, ptr @Gstatic_int1, align 4 1286; TUNIT-NEXT: [[ADD:%.*]] = add i32 [[LGS2]], [[LGS3]] 1287; TUNIT-NEXT: ret i32 [[ADD]] 1288; 1289; CGSCC: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn 1290; CGSCC-LABEL: define {{[^@]+}}@assume_read_global_good 1291; CGSCC-SAME: () #[[ATTR6:[0-9]+]] { 1292; CGSCC-NEXT: [[LGS1:%.*]] = load i32, ptr @Gstatic_int1, align 4 1293; CGSCC-NEXT: [[C:%.*]] = icmp eq i32 [[LGS1]], 42 1294; CGSCC-NEXT: call void @llvm.assume(i1 noundef [[C]]) #[[ATTR8]] 1295; CGSCC-NEXT: [[LGS2:%.*]] = load i32, ptr @Gstatic_int1, align 4 1296; CGSCC-NEXT: store i32 17, ptr @Gstatic_int1, align 4 1297; CGSCC-NEXT: [[LGS3:%.*]] = load i32, ptr @Gstatic_int1, align 4 1298; CGSCC-NEXT: [[ADD:%.*]] = add i32 [[LGS2]], [[LGS3]] 1299; CGSCC-NEXT: ret i32 [[ADD]] 1300; 1301 %lgs1 = load i32, ptr @Gstatic_int1 1302 %c = icmp eq i32 %lgs1, 42 1303 call void @llvm.assume(i1 %c) 1304 %lgs2 = load i32, ptr @Gstatic_int1 1305 store i32 13, ptr @Gstatic_int1, align 4 1306 store i32 17, ptr @Gstatic_int1, align 4 1307 %lgs3 = load i32, ptr @Gstatic_int1 1308 %add = add i32 %lgs2, %lgs3 1309 ret i32 %add 1310} 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 willreturn 1316; TUNIT-LABEL: define {{[^@]+}}@assume_read_global_bad 1317; 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 4 1319; TUNIT-NEXT: [[C:%.*]] = icmp eq i32 [[LGS1]], 42 1320; TUNIT-NEXT: store i32 13, ptr [[P]], align 4 1321; TUNIT-NEXT: call void @llvm.assume(i1 noundef [[C]]) #[[ATTR7]] 1322; TUNIT-NEXT: [[LGS2:%.*]] = load i32, ptr @Gstatic_int2, align 4 1323; TUNIT-NEXT: store i32 17, ptr @Gstatic_int2, align 4 1324; TUNIT-NEXT: ret i32 [[LGS2]] 1325; 1326; CGSCC: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn 1327; CGSCC-LABEL: define {{[^@]+}}@assume_read_global_bad 1328; 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 4 1330; CGSCC-NEXT: [[C:%.*]] = icmp eq i32 [[LGS1]], 42 1331; CGSCC-NEXT: store i32 13, ptr [[P]], align 4 1332; CGSCC-NEXT: call void @llvm.assume(i1 noundef [[C]]) #[[ATTR8]] 1333; CGSCC-NEXT: [[LGS2:%.*]] = load i32, ptr @Gstatic_int2, align 4 1334; CGSCC-NEXT: store i32 17, ptr @Gstatic_int2, align 4 1335; CGSCC-NEXT: ret i32 [[LGS2]] 1336; 1337 %lgs1 = load i32, ptr @Gstatic_int2 1338 %c = icmp eq i32 %lgs1, 42 1339 store i32 13, ptr %p, align 4 1340 call void @llvm.assume(i1 %c) 1341 %lgs2 = load i32, ptr @Gstatic_int2 1342 store i32 17, ptr @Gstatic_int2, align 4 1343 ret i32 %lgs2 1344} 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_globals 1350; TUNIT-SAME: () #[[ATTR6:[0-9]+]] { 1351; TUNIT-NEXT: store i32 42, ptr @Gstatic_int1, align 4 1352; TUNIT-NEXT: store i32 42, ptr @Gstatic_int2, align 4 1353; TUNIT-NEXT: ret void 1354; 1355; CGSCC: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(write) 1356; CGSCC-LABEL: define {{[^@]+}}@assume_write_globals 1357; CGSCC-SAME: () #[[ATTR7:[0-9]+]] { 1358; CGSCC-NEXT: store i32 42, ptr @Gstatic_int1, align 4 1359; CGSCC-NEXT: store i32 42, ptr @Gstatic_int2, align 4 1360; CGSCC-NEXT: ret void 1361; 1362 store i32 42, ptr @Gstatic_int1, align 4 1363 store i32 42, ptr @Gstatic_int2, align 4 1364 ret void 1365} 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