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%struct.S = type { i32, i32, i32, float, float, float } 6 7@globalBytes = global [1024 x i8] zeroinitializer, align 16 8@Gint1 = global i32 zeroinitializer, align 4 9@Gint2 = global i32 zeroinitializer, align 4 10@Gstatic_int1 = internal global i32 zeroinitializer, align 4 11@Gstatic_int2 = internal global i32 zeroinitializer, align 4 12@Gstatic_int3 = internal global i32 zeroinitializer, align 4 13@Gstatic_undef_int1 = internal global i32 undef, align 4 14@Gstatic_undef_int2 = internal global i32 undef, align 4 15@GI1 = internal global i32 undef, align 4 16@GI2 = internal global i32 undef, align 4 17@Gs1 = internal global %struct.S undef, align 4 18@Gs2 = internal global %struct.S zeroinitializer, align 4 19@Vs1 = internal global %struct.S undef, align 4 20@Vs2 = internal global %struct.S undef, align 4 21@GBytes = internal global [1024 x i8] zeroinitializer, align 16 22@Flag0 = global i32 0, align 4 23@Flag1 = internal global i32 undef, align 4 24@Flag2 = internal global i32 undef, align 4 25@Flag4 = internal global i32 undef, align 4 26@Flag3 = internal global i32 zeroinitializer, align 4 27@a1 = internal global i32 zeroinitializer 28@a2 = internal global i32 zeroinitializer 29@a3 = internal global i32 undef 30@bytes1 = internal global i32 undef 31@bytes2 = internal global i32 undef 32@rec_storage = internal global i32 undef 33 34;. 35; CHECK: @globalBytes = global [1024 x i8] zeroinitializer, align 16 36; CHECK: @Gint1 = global i32 0, align 4 37; CHECK: @Gint2 = global i32 0, align 4 38; CHECK: @Gstatic_int1 = internal global i32 0, align 4 39; CHECK: @Gstatic_int2 = internal global i32 0, align 4 40; CHECK: @Gstatic_int3 = internal global i32 0, align 4 41; CHECK: @Gstatic_undef_int1 = internal global i32 undef, align 4 42; CHECK: @Gstatic_undef_int2 = internal global i32 undef, align 4 43; CHECK: @GI1 = internal global i32 undef, align 4 44; CHECK: @GI2 = internal global i32 undef, align 4 45; CHECK: @Gs1 = internal global %struct.S undef, align 4 46; CHECK: @Gs2 = internal global %struct.S zeroinitializer, align 4 47; CHECK: @Vs1 = internal global %struct.S undef, align 4 48; CHECK: @Vs2 = internal global %struct.S undef, align 4 49; CHECK: @GBytes = internal global [1024 x i8] zeroinitializer, align 16 50; CHECK: @Flag0 = global i32 0, align 4 51; CHECK: @Flag1 = internal global i32 undef, align 4 52; CHECK: @Flag2 = internal global i32 undef, align 4 53; CHECK: @Flag4 = internal global i32 undef, align 4 54; CHECK: @Flag3 = internal global i32 0, align 4 55; CHECK: @a1 = internal global i32 0 56; CHECK: @a2 = internal global i32 0 57; CHECK: @a3 = internal global i32 undef 58; CHECK: @bytes1 = internal global i32 undef 59; CHECK: @bytes2 = internal global i32 undef 60; CHECK: @rec_storage = internal global i32 undef 61; CHECK: @global = internal global %struct.STy zeroinitializer, align 8 62; CHECK: @G = internal global i32 0, align 4 63; CHECK: @GC = internal global i32 undef, align 4 64; CHECK: @GRS = internal thread_local global i32 undef 65; CHECK: @GRS2 = global i32 undef 66;. 67define void @write_arg(ptr %p, i32 %v) { 68; CHECK: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(argmem: write) 69; CHECK-LABEL: define {{[^@]+}}@write_arg 70; CHECK-SAME: (ptr nofree noundef nonnull writeonly align 4 captures(none) dereferenceable(4) [[P:%.*]], i32 [[V:%.*]]) #[[ATTR0:[0-9]+]] { 71; CHECK-NEXT: entry: 72; CHECK-NEXT: store i32 [[V]], ptr [[P]], align 4, !tbaa [[TBAA3:![0-9]+]] 73; CHECK-NEXT: ret void 74; 75entry: 76 store i32 %v, ptr %p, align 4, !tbaa !3 77 ret void 78} 79 80define void @write_random(ptr %p) { 81; CHECK-LABEL: define {{[^@]+}}@write_random 82; CHECK-SAME: (ptr nofree writeonly captures(none) [[P:%.*]]) { 83; CHECK-NEXT: entry: 84; CHECK-NEXT: [[CALL:%.*]] = call i32 (...) @random() 85; CHECK-NEXT: store i32 [[CALL]], ptr [[P]], align 4, !tbaa [[TBAA3]] 86; CHECK-NEXT: ret void 87; 88entry: 89 %call = call i32 (...) @random() 90 store i32 %call, ptr %p, align 4, !tbaa !3 91 ret void 92} 93 94declare i32 @random(...) 95 96; struct S local_alloca_simplifiable_1(void) { 97; struct S s; 98; s.f1 = 1.1; 99; s.f2 = 2.2; 100; s.f3 = 3.3; 101; write_arg(&s.i1, 1); 102; write_arg(&s.i2, 2); 103; write_arg(&s.i3, 3); 104; struct S r; 105; r.f1 = s.f1; 106; r.f2 = s.f2 * 2; 107; r.f3 = s.f3 + s.f1; 108; r.i1 = s.i1; 109; r.i2 = s.i2 * 2; 110; r.i3 = s.i3 + s.i1; 111; return r; 112; } 113define void @local_alloca_simplifiable_1(ptr noalias sret(%struct.S) align 4 %agg.result) { 114; TUNIT: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(argmem: readwrite) 115; TUNIT-LABEL: define {{[^@]+}}@local_alloca_simplifiable_1 116; TUNIT-SAME: (ptr noalias nofree writeonly sret([[STRUCT_S:%.*]]) align 4 captures(none) dereferenceable_or_null(24) [[AGG_RESULT:%.*]]) #[[ATTR1:[0-9]+]] { 117; TUNIT-NEXT: entry: 118; TUNIT-NEXT: [[S:%.*]] = alloca [[STRUCT_S]], align 4 119; TUNIT-NEXT: call void @llvm.lifetime.start.p0(i64 noundef 24, ptr noalias nofree noundef nonnull align 4 captures(none) dereferenceable(24) [[S]]) #[[ATTR17:[0-9]+]] 120; TUNIT-NEXT: [[F1:%.*]] = getelementptr inbounds [[STRUCT_S]], ptr [[S]], i64 0, i32 3 121; TUNIT-NEXT: [[F2:%.*]] = getelementptr inbounds [[STRUCT_S]], ptr [[S]], i64 0, i32 4 122; TUNIT-NEXT: [[F3:%.*]] = getelementptr inbounds [[STRUCT_S]], ptr [[S]], i64 0, i32 5 123; TUNIT-NEXT: call void @write_arg(ptr noalias nofree noundef nonnull writeonly align 4 captures(none) dereferenceable(24) [[S]], i32 noundef 1) #[[ATTR18:[0-9]+]] 124; TUNIT-NEXT: [[I2:%.*]] = getelementptr inbounds [[STRUCT_S]], ptr [[S]], i64 0, i32 1 125; TUNIT-NEXT: call void @write_arg(ptr nofree noundef nonnull writeonly align 4 captures(none) dereferenceable(20) [[I2]], i32 noundef 2) #[[ATTR18]] 126; TUNIT-NEXT: [[I3:%.*]] = getelementptr inbounds [[STRUCT_S]], ptr [[S]], i64 0, i32 2 127; TUNIT-NEXT: call void @write_arg(ptr nofree noundef nonnull writeonly align 4 captures(none) dereferenceable(16) [[I3]], i32 noundef 3) #[[ATTR18]] 128; TUNIT-NEXT: [[F12:%.*]] = getelementptr inbounds [[STRUCT_S]], ptr [[AGG_RESULT]], i64 0, i32 3 129; TUNIT-NEXT: store float 0x3FF19999A0000000, ptr [[F12]], align 4, !tbaa [[TBAA7:![0-9]+]] 130; TUNIT-NEXT: [[F24:%.*]] = getelementptr inbounds [[STRUCT_S]], ptr [[AGG_RESULT]], i64 0, i32 4 131; TUNIT-NEXT: store float 0x40119999A0000000, ptr [[F24]], align 4, !tbaa [[TBAA10:![0-9]+]] 132; TUNIT-NEXT: [[F37:%.*]] = getelementptr inbounds [[STRUCT_S]], ptr [[AGG_RESULT]], i64 0, i32 5 133; TUNIT-NEXT: store float 0x40119999A0000000, ptr [[F37]], align 4, !tbaa [[TBAA11:![0-9]+]] 134; TUNIT-NEXT: store i32 1, ptr [[AGG_RESULT]], align 4, !tbaa [[TBAA12:![0-9]+]] 135; TUNIT-NEXT: [[I212:%.*]] = getelementptr inbounds [[STRUCT_S]], ptr [[AGG_RESULT]], i64 0, i32 1 136; TUNIT-NEXT: store i32 4, ptr [[I212]], align 4, !tbaa [[TBAA13:![0-9]+]] 137; TUNIT-NEXT: [[I316:%.*]] = getelementptr inbounds [[STRUCT_S]], ptr [[AGG_RESULT]], i64 0, i32 2 138; TUNIT-NEXT: store i32 4, ptr [[I316]], align 4, !tbaa [[TBAA14:![0-9]+]] 139; TUNIT-NEXT: call void @llvm.lifetime.end.p0(i64 noundef 24, ptr noalias nofree noundef nonnull align 4 captures(none) dereferenceable(24) [[S]]) #[[ATTR17]] 140; TUNIT-NEXT: ret void 141; 142; CGSCC: Function Attrs: mustprogress nofree nosync nounwind willreturn memory(argmem: readwrite) 143; CGSCC-LABEL: define {{[^@]+}}@local_alloca_simplifiable_1 144; CGSCC-SAME: (ptr noalias nofree noundef nonnull writeonly sret([[STRUCT_S:%.*]]) align 4 captures(none) dereferenceable(24) [[AGG_RESULT:%.*]]) #[[ATTR1:[0-9]+]] { 145; CGSCC-NEXT: entry: 146; CGSCC-NEXT: [[S:%.*]] = alloca [[STRUCT_S]], align 4 147; CGSCC-NEXT: call void @llvm.lifetime.start.p0(i64 noundef 24, ptr noalias nofree noundef nonnull align 4 captures(none) dereferenceable(24) [[S]]) #[[ATTR20:[0-9]+]] 148; CGSCC-NEXT: [[F1:%.*]] = getelementptr inbounds [[STRUCT_S]], ptr [[S]], i64 0, i32 3 149; CGSCC-NEXT: store float 0x3FF19999A0000000, ptr [[F1]], align 4, !tbaa [[TBAA7:![0-9]+]] 150; CGSCC-NEXT: [[F2:%.*]] = getelementptr inbounds [[STRUCT_S]], ptr [[S]], i64 0, i32 4 151; CGSCC-NEXT: store float 0x40019999A0000000, ptr [[F2]], align 4, !tbaa [[TBAA10:![0-9]+]] 152; CGSCC-NEXT: [[F3:%.*]] = getelementptr inbounds [[STRUCT_S]], ptr [[S]], i64 0, i32 5 153; CGSCC-NEXT: store float 0x400A666660000000, ptr [[F3]], align 4, !tbaa [[TBAA11:![0-9]+]] 154; CGSCC-NEXT: call void @write_arg(ptr noalias nofree noundef nonnull writeonly align 4 captures(none) dereferenceable(24) [[S]], i32 noundef 1) #[[ATTR21:[0-9]+]] 155; CGSCC-NEXT: [[I2:%.*]] = getelementptr inbounds [[STRUCT_S]], ptr [[S]], i64 0, i32 1 156; CGSCC-NEXT: call void @write_arg(ptr nofree noundef nonnull writeonly align 4 captures(none) dereferenceable(20) [[I2]], i32 noundef 2) #[[ATTR21]] 157; CGSCC-NEXT: [[I3:%.*]] = getelementptr inbounds [[STRUCT_S]], ptr [[S]], i64 0, i32 2 158; CGSCC-NEXT: call void @write_arg(ptr nofree noundef nonnull writeonly align 4 captures(none) dereferenceable(16) [[I3]], i32 noundef 3) #[[ATTR21]] 159; CGSCC-NEXT: [[F11:%.*]] = getelementptr inbounds [[STRUCT_S]], ptr [[S]], i64 0, i32 3 160; CGSCC-NEXT: [[I4:%.*]] = load float, ptr [[F11]], align 4, !tbaa [[TBAA7]] 161; CGSCC-NEXT: [[F12:%.*]] = getelementptr inbounds [[STRUCT_S]], ptr [[AGG_RESULT]], i64 0, i32 3 162; CGSCC-NEXT: store float [[I4]], ptr [[F12]], align 4, !tbaa [[TBAA7]] 163; CGSCC-NEXT: [[F23:%.*]] = getelementptr inbounds [[STRUCT_S]], ptr [[S]], i64 0, i32 4 164; CGSCC-NEXT: [[I5:%.*]] = load float, ptr [[F23]], align 4, !tbaa [[TBAA10]] 165; CGSCC-NEXT: [[MUL:%.*]] = fmul float [[I5]], 2.000000e+00 166; CGSCC-NEXT: [[F24:%.*]] = getelementptr inbounds [[STRUCT_S]], ptr [[AGG_RESULT]], i64 0, i32 4 167; CGSCC-NEXT: store float [[MUL]], ptr [[F24]], align 4, !tbaa [[TBAA10]] 168; CGSCC-NEXT: [[F35:%.*]] = getelementptr inbounds [[STRUCT_S]], ptr [[S]], i64 0, i32 5 169; CGSCC-NEXT: [[I6:%.*]] = load float, ptr [[F35]], align 4, !tbaa [[TBAA11]] 170; CGSCC-NEXT: [[F16:%.*]] = getelementptr inbounds [[STRUCT_S]], ptr [[S]], i64 0, i32 3 171; CGSCC-NEXT: [[I7:%.*]] = load float, ptr [[F16]], align 4, !tbaa [[TBAA7]] 172; CGSCC-NEXT: [[ADD:%.*]] = fadd float [[I6]], [[I7]] 173; CGSCC-NEXT: [[F37:%.*]] = getelementptr inbounds [[STRUCT_S]], ptr [[AGG_RESULT]], i64 0, i32 5 174; CGSCC-NEXT: store float [[ADD]], ptr [[F37]], align 4, !tbaa [[TBAA11]] 175; CGSCC-NEXT: [[I8:%.*]] = load i32, ptr [[S]], align 4, !tbaa [[TBAA12:![0-9]+]] 176; CGSCC-NEXT: store i32 [[I8]], ptr [[AGG_RESULT]], align 4, !tbaa [[TBAA12]] 177; CGSCC-NEXT: [[I210:%.*]] = getelementptr inbounds [[STRUCT_S]], ptr [[S]], i64 0, i32 1 178; CGSCC-NEXT: [[I9:%.*]] = load i32, ptr [[I210]], align 4, !tbaa [[TBAA13:![0-9]+]] 179; CGSCC-NEXT: [[MUL11:%.*]] = shl nsw i32 [[I9]], 1 180; CGSCC-NEXT: [[I212:%.*]] = getelementptr inbounds [[STRUCT_S]], ptr [[AGG_RESULT]], i64 0, i32 1 181; CGSCC-NEXT: store i32 [[MUL11]], ptr [[I212]], align 4, !tbaa [[TBAA13]] 182; CGSCC-NEXT: [[I313:%.*]] = getelementptr inbounds [[STRUCT_S]], ptr [[S]], i64 0, i32 2 183; CGSCC-NEXT: [[I10:%.*]] = load i32, ptr [[I313]], align 4, !tbaa [[TBAA14:![0-9]+]] 184; CGSCC-NEXT: [[I11:%.*]] = load i32, ptr [[S]], align 4, !tbaa [[TBAA12]] 185; CGSCC-NEXT: [[ADD15:%.*]] = add nsw i32 [[I10]], [[I11]] 186; CGSCC-NEXT: [[I316:%.*]] = getelementptr inbounds [[STRUCT_S]], ptr [[AGG_RESULT]], i64 0, i32 2 187; CGSCC-NEXT: store i32 [[ADD15]], ptr [[I316]], align 4, !tbaa [[TBAA14]] 188; CGSCC-NEXT: call void @llvm.lifetime.end.p0(i64 noundef 24, ptr noalias nofree noundef nonnull align 4 captures(none) dereferenceable(24) [[S]]) #[[ATTR20]] 189; CGSCC-NEXT: ret void 190; 191entry: 192 %s = alloca %struct.S, align 4 193 call void @llvm.lifetime.start.p0(i64 24, ptr nonnull %s) 194 %f1 = getelementptr inbounds %struct.S, ptr %s, i64 0, i32 3 195 store float 0x3FF19999A0000000, ptr %f1, align 4, !tbaa !7 196 %f2 = getelementptr inbounds %struct.S, ptr %s, i64 0, i32 4 197 store float 0x40019999A0000000, ptr %f2, align 4, !tbaa !10 198 %f3 = getelementptr inbounds %struct.S, ptr %s, i64 0, i32 5 199 store float 0x400A666660000000, ptr %f3, align 4, !tbaa !11 200 call void @write_arg(ptr nonnull %s, i32 1) 201 %i2 = getelementptr inbounds %struct.S, ptr %s, i64 0, i32 1 202 call void @write_arg(ptr nonnull %i2, i32 2) 203 %i3 = getelementptr inbounds %struct.S, ptr %s, i64 0, i32 2 204 call void @write_arg(ptr nonnull %i3, i32 3) 205 %f11 = getelementptr inbounds %struct.S, ptr %s, i64 0, i32 3 206 %i4 = load float, ptr %f11, align 4, !tbaa !7 207 %f12 = getelementptr inbounds %struct.S, ptr %agg.result, i64 0, i32 3 208 store float %i4, ptr %f12, align 4, !tbaa !7 209 %f23 = getelementptr inbounds %struct.S, ptr %s, i64 0, i32 4 210 %i5 = load float, ptr %f23, align 4, !tbaa !10 211 %mul = fmul float %i5, 2.000000e+00 212 %f24 = getelementptr inbounds %struct.S, ptr %agg.result, i64 0, i32 4 213 store float %mul, ptr %f24, align 4, !tbaa !10 214 %f35 = getelementptr inbounds %struct.S, ptr %s, i64 0, i32 5 215 %i6 = load float, ptr %f35, align 4, !tbaa !11 216 %f16 = getelementptr inbounds %struct.S, ptr %s, i64 0, i32 3 217 %i7 = load float, ptr %f16, align 4, !tbaa !7 218 %add = fadd float %i6, %i7 219 %f37 = getelementptr inbounds %struct.S, ptr %agg.result, i64 0, i32 5 220 store float %add, ptr %f37, align 4, !tbaa !11 221 %i8 = load i32, ptr %s, align 4, !tbaa !12 222 store i32 %i8, ptr %agg.result, align 4, !tbaa !12 223 %i210 = getelementptr inbounds %struct.S, ptr %s, i64 0, i32 1 224 %i9 = load i32, ptr %i210, align 4, !tbaa !13 225 %mul11 = shl nsw i32 %i9, 1 226 %i212 = getelementptr inbounds %struct.S, ptr %agg.result, i64 0, i32 1 227 store i32 %mul11, ptr %i212, align 4, !tbaa !13 228 %i313 = getelementptr inbounds %struct.S, ptr %s, i64 0, i32 2 229 %i10 = load i32, ptr %i313, align 4, !tbaa !14 230 %i11 = load i32, ptr %s, align 4, !tbaa !12 231 %add15 = add nsw i32 %i10, %i11 232 %i316 = getelementptr inbounds %struct.S, ptr %agg.result, i64 0, i32 2 233 store i32 %add15, ptr %i316, align 4, !tbaa !14 234 call void @llvm.lifetime.end.p0(i64 24, ptr nonnull %s) 235 ret void 236} 237 238declare void @llvm.lifetime.start.p0(i64 immarg, ptr nocapture) 239 240declare void @llvm.lifetime.end.p0(i64 immarg, ptr nocapture) 241 242; void local_alloca_simplifiable_2(void) { 243; char Bytes[1024]; 244; for (int i = 0; i < 100; ++i) 245; Bytes[i * 10] = 0; 246; for (int i = 0; i < 10; ++i) 247; ((float *)Bytes)[i * 10 + 1] = 0; 248; for (int i = 0; i < 20; ++i) 249; ((long long int *)Bytes)[i * 10 + 2] = 0; 250; Bytes[1023] = 0; 251; write_arg((int *)&Bytes[500], 0); 252; struct S R; 253; for (int i = 0; i < 1024; ++i) 254; globalBytes[i] = Bytes[i]; 255; } 256; 257define void @local_alloca_simplifiable_2() { 258; TUNIT: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn 259; TUNIT-LABEL: define {{[^@]+}}@local_alloca_simplifiable_2 260; TUNIT-SAME: () #[[ATTR3:[0-9]+]] { 261; TUNIT-NEXT: entry: 262; TUNIT-NEXT: [[BYTES:%.*]] = alloca [1024 x i8], align 16 263; TUNIT-NEXT: call void @llvm.lifetime.start.p0(i64 noundef 1024, ptr noalias nofree noundef nonnull align 16 captures(none) dereferenceable(1024) [[BYTES]]) #[[ATTR17]] 264; TUNIT-NEXT: br label [[FOR_COND:%.*]] 265; TUNIT: for.cond: 266; TUNIT-NEXT: [[INDVARS_IV:%.*]] = phi i64 [ [[INDVARS_IV_NEXT:%.*]], [[FOR_INC:%.*]] ], [ 0, [[ENTRY:%.*]] ] 267; TUNIT-NEXT: [[EXITCOND:%.*]] = icmp ne i64 [[INDVARS_IV]], 100 268; TUNIT-NEXT: br i1 [[EXITCOND]], label [[FOR_BODY:%.*]], label [[FOR_COND_CLEANUP:%.*]] 269; TUNIT: for.cond.cleanup: 270; TUNIT-NEXT: br label [[FOR_END:%.*]] 271; TUNIT: for.body: 272; TUNIT-NEXT: [[I15:%.*]] = mul nuw nsw i64 [[INDVARS_IV]], 10 273; TUNIT-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds [1024 x i8], ptr [[BYTES]], i64 0, i64 [[I15]] 274; TUNIT-NEXT: br label [[FOR_INC]] 275; TUNIT: for.inc: 276; TUNIT-NEXT: [[INDVARS_IV_NEXT]] = add nuw nsw i64 [[INDVARS_IV]], 1 277; TUNIT-NEXT: br label [[FOR_COND]], !llvm.loop [[LOOP15:![0-9]+]] 278; TUNIT: for.end: 279; TUNIT-NEXT: br label [[FOR_COND2:%.*]] 280; TUNIT: for.cond2: 281; TUNIT-NEXT: [[INDVARS_IV2:%.*]] = phi i64 [ [[INDVARS_IV_NEXT3:%.*]], [[FOR_INC9:%.*]] ], [ 0, [[FOR_END]] ] 282; TUNIT-NEXT: [[EXITCOND6:%.*]] = icmp ne i64 [[INDVARS_IV2]], 10 283; TUNIT-NEXT: br i1 [[EXITCOND6]], label [[FOR_BODY5:%.*]], label [[FOR_COND_CLEANUP4:%.*]] 284; TUNIT: for.cond.cleanup4: 285; TUNIT-NEXT: br label [[FOR_END11:%.*]] 286; TUNIT: for.body5: 287; TUNIT-NEXT: [[I17:%.*]] = mul nuw nsw i64 [[INDVARS_IV2]], 10 288; TUNIT-NEXT: [[I18:%.*]] = or i64 [[I17]], 1 289; TUNIT-NEXT: [[ARRAYIDX8:%.*]] = getelementptr inbounds float, ptr [[BYTES]], i64 [[I18]] 290; TUNIT-NEXT: br label [[FOR_INC9]] 291; TUNIT: for.inc9: 292; TUNIT-NEXT: [[INDVARS_IV_NEXT3]] = add nuw nsw i64 [[INDVARS_IV2]], 1 293; TUNIT-NEXT: br label [[FOR_COND2]], !llvm.loop [[LOOP17:![0-9]+]] 294; TUNIT: for.end11: 295; TUNIT-NEXT: br label [[FOR_COND13:%.*]] 296; TUNIT: for.cond13: 297; TUNIT-NEXT: [[INDVARS_IV7:%.*]] = phi i64 [ [[INDVARS_IV_NEXT8:%.*]], [[FOR_INC22:%.*]] ], [ 0, [[FOR_END11]] ] 298; TUNIT-NEXT: [[EXITCOND11:%.*]] = icmp ne i64 [[INDVARS_IV7]], 20 299; TUNIT-NEXT: br i1 [[EXITCOND11]], label [[FOR_BODY16:%.*]], label [[FOR_COND_CLEANUP15:%.*]] 300; TUNIT: for.cond.cleanup15: 301; TUNIT-NEXT: br label [[FOR_END24:%.*]] 302; TUNIT: for.body16: 303; TUNIT-NEXT: [[I20:%.*]] = mul nuw nsw i64 [[INDVARS_IV7]], 10 304; TUNIT-NEXT: [[I21:%.*]] = add nuw nsw i64 [[I20]], 2 305; TUNIT-NEXT: [[ARRAYIDX21:%.*]] = getelementptr inbounds i64, ptr [[BYTES]], i64 [[I21]] 306; TUNIT-NEXT: br label [[FOR_INC22]] 307; TUNIT: for.inc22: 308; TUNIT-NEXT: [[INDVARS_IV_NEXT8]] = add nuw nsw i64 [[INDVARS_IV7]], 1 309; TUNIT-NEXT: br label [[FOR_COND13]], !llvm.loop [[LOOP18:![0-9]+]] 310; TUNIT: for.end24: 311; TUNIT-NEXT: [[ARRAYIDX25:%.*]] = getelementptr inbounds [1024 x i8], ptr [[BYTES]], i64 0, i64 1023 312; TUNIT-NEXT: [[ARRAYIDX26:%.*]] = getelementptr inbounds [1024 x i8], ptr [[BYTES]], i64 0, i64 500 313; TUNIT-NEXT: call void @write_arg(ptr nofree noundef nonnull writeonly align 4 captures(none) dereferenceable(524) [[ARRAYIDX26]], i32 noundef 0) #[[ATTR18]] 314; TUNIT-NEXT: br label [[FOR_COND28:%.*]] 315; TUNIT: for.cond28: 316; TUNIT-NEXT: [[INDVARS_IV12:%.*]] = phi i64 [ [[INDVARS_IV_NEXT13:%.*]], [[FOR_INC36:%.*]] ], [ 0, [[FOR_END24]] ] 317; TUNIT-NEXT: [[EXITCOND14:%.*]] = icmp ne i64 [[INDVARS_IV12]], 1024 318; TUNIT-NEXT: br i1 [[EXITCOND14]], label [[FOR_BODY31:%.*]], label [[FOR_COND_CLEANUP30:%.*]] 319; TUNIT: for.cond.cleanup30: 320; TUNIT-NEXT: br label [[FOR_END38:%.*]] 321; TUNIT: for.body31: 322; TUNIT-NEXT: [[ARRAYIDX35:%.*]] = getelementptr inbounds [1024 x i8], ptr @globalBytes, i64 0, i64 [[INDVARS_IV12]] 323; TUNIT-NEXT: store i8 0, ptr [[ARRAYIDX35]], align 1, !tbaa [[TBAA19:![0-9]+]] 324; TUNIT-NEXT: br label [[FOR_INC36]] 325; TUNIT: for.inc36: 326; TUNIT-NEXT: [[INDVARS_IV_NEXT13]] = add nuw nsw i64 [[INDVARS_IV12]], 1 327; TUNIT-NEXT: br label [[FOR_COND28]], !llvm.loop [[LOOP20:![0-9]+]] 328; TUNIT: for.end38: 329; TUNIT-NEXT: call void @llvm.lifetime.end.p0(i64 noundef 1024, ptr noalias nofree noundef nonnull align 16 captures(none) dereferenceable(1024) [[BYTES]]) #[[ATTR17]] 330; TUNIT-NEXT: ret void 331; 332; CGSCC: Function Attrs: mustprogress nofree nosync nounwind willreturn 333; CGSCC-LABEL: define {{[^@]+}}@local_alloca_simplifiable_2 334; CGSCC-SAME: () #[[ATTR3:[0-9]+]] { 335; CGSCC-NEXT: entry: 336; CGSCC-NEXT: [[BYTES:%.*]] = alloca [1024 x i8], align 16 337; CGSCC-NEXT: call void @llvm.lifetime.start.p0(i64 noundef 1024, ptr noalias nofree noundef nonnull align 16 captures(none) dereferenceable(1024) [[BYTES]]) #[[ATTR20]] 338; CGSCC-NEXT: br label [[FOR_COND:%.*]] 339; CGSCC: for.cond: 340; CGSCC-NEXT: [[INDVARS_IV:%.*]] = phi i64 [ [[INDVARS_IV_NEXT:%.*]], [[FOR_INC:%.*]] ], [ 0, [[ENTRY:%.*]] ] 341; CGSCC-NEXT: [[EXITCOND:%.*]] = icmp ne i64 [[INDVARS_IV]], 100 342; CGSCC-NEXT: br i1 [[EXITCOND]], label [[FOR_BODY:%.*]], label [[FOR_COND_CLEANUP:%.*]] 343; CGSCC: for.cond.cleanup: 344; CGSCC-NEXT: br label [[FOR_END:%.*]] 345; CGSCC: for.body: 346; CGSCC-NEXT: [[I15:%.*]] = mul nuw nsw i64 [[INDVARS_IV]], 10 347; CGSCC-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds [1024 x i8], ptr [[BYTES]], i64 0, i64 [[I15]] 348; CGSCC-NEXT: store i8 0, ptr [[ARRAYIDX]], align 2, !tbaa [[TBAA15:![0-9]+]] 349; CGSCC-NEXT: br label [[FOR_INC]] 350; CGSCC: for.inc: 351; CGSCC-NEXT: [[INDVARS_IV_NEXT]] = add nuw nsw i64 [[INDVARS_IV]], 1 352; CGSCC-NEXT: br label [[FOR_COND]], !llvm.loop [[LOOP16:![0-9]+]] 353; CGSCC: for.end: 354; CGSCC-NEXT: br label [[FOR_COND2:%.*]] 355; CGSCC: for.cond2: 356; CGSCC-NEXT: [[INDVARS_IV2:%.*]] = phi i64 [ [[INDVARS_IV_NEXT3:%.*]], [[FOR_INC9:%.*]] ], [ 0, [[FOR_END]] ] 357; CGSCC-NEXT: [[EXITCOND6:%.*]] = icmp ne i64 [[INDVARS_IV2]], 10 358; CGSCC-NEXT: br i1 [[EXITCOND6]], label [[FOR_BODY5:%.*]], label [[FOR_COND_CLEANUP4:%.*]] 359; CGSCC: for.cond.cleanup4: 360; CGSCC-NEXT: br label [[FOR_END11:%.*]] 361; CGSCC: for.body5: 362; CGSCC-NEXT: [[I17:%.*]] = mul nuw nsw i64 [[INDVARS_IV2]], 10 363; CGSCC-NEXT: [[I18:%.*]] = or i64 [[I17]], 1 364; CGSCC-NEXT: [[ARRAYIDX8:%.*]] = getelementptr inbounds float, ptr [[BYTES]], i64 [[I18]] 365; CGSCC-NEXT: store float 0.000000e+00, ptr [[ARRAYIDX8]], align 4, !tbaa [[TBAA18:![0-9]+]] 366; CGSCC-NEXT: br label [[FOR_INC9]] 367; CGSCC: for.inc9: 368; CGSCC-NEXT: [[INDVARS_IV_NEXT3]] = add nuw nsw i64 [[INDVARS_IV2]], 1 369; CGSCC-NEXT: br label [[FOR_COND2]], !llvm.loop [[LOOP19:![0-9]+]] 370; CGSCC: for.end11: 371; CGSCC-NEXT: br label [[FOR_COND13:%.*]] 372; CGSCC: for.cond13: 373; CGSCC-NEXT: [[INDVARS_IV7:%.*]] = phi i64 [ [[INDVARS_IV_NEXT8:%.*]], [[FOR_INC22:%.*]] ], [ 0, [[FOR_END11]] ] 374; CGSCC-NEXT: [[EXITCOND11:%.*]] = icmp ne i64 [[INDVARS_IV7]], 20 375; CGSCC-NEXT: br i1 [[EXITCOND11]], label [[FOR_BODY16:%.*]], label [[FOR_COND_CLEANUP15:%.*]] 376; CGSCC: for.cond.cleanup15: 377; CGSCC-NEXT: br label [[FOR_END24:%.*]] 378; CGSCC: for.body16: 379; CGSCC-NEXT: [[I20:%.*]] = mul nuw nsw i64 [[INDVARS_IV7]], 10 380; CGSCC-NEXT: [[I21:%.*]] = add nuw nsw i64 [[I20]], 2 381; CGSCC-NEXT: [[ARRAYIDX21:%.*]] = getelementptr inbounds i64, ptr [[BYTES]], i64 [[I21]] 382; CGSCC-NEXT: store i64 0, ptr [[ARRAYIDX21]], align 16, !tbaa [[TBAA20:![0-9]+]] 383; CGSCC-NEXT: br label [[FOR_INC22]] 384; CGSCC: for.inc22: 385; CGSCC-NEXT: [[INDVARS_IV_NEXT8]] = add nuw nsw i64 [[INDVARS_IV7]], 1 386; CGSCC-NEXT: br label [[FOR_COND13]], !llvm.loop [[LOOP22:![0-9]+]] 387; CGSCC: for.end24: 388; CGSCC-NEXT: [[ARRAYIDX25:%.*]] = getelementptr inbounds [1024 x i8], ptr [[BYTES]], i64 0, i64 1023 389; CGSCC-NEXT: store i8 0, ptr [[ARRAYIDX25]], align 1, !tbaa [[TBAA15]] 390; CGSCC-NEXT: [[ARRAYIDX26:%.*]] = getelementptr inbounds [1024 x i8], ptr [[BYTES]], i64 0, i64 500 391; CGSCC-NEXT: call void @write_arg(ptr nofree noundef nonnull writeonly align 4 captures(none) dereferenceable(524) [[ARRAYIDX26]], i32 noundef 0) #[[ATTR21]] 392; CGSCC-NEXT: br label [[FOR_COND28:%.*]] 393; CGSCC: for.cond28: 394; CGSCC-NEXT: [[INDVARS_IV12:%.*]] = phi i64 [ [[INDVARS_IV_NEXT13:%.*]], [[FOR_INC36:%.*]] ], [ 0, [[FOR_END24]] ] 395; CGSCC-NEXT: [[EXITCOND14:%.*]] = icmp ne i64 [[INDVARS_IV12]], 1024 396; CGSCC-NEXT: br i1 [[EXITCOND14]], label [[FOR_BODY31:%.*]], label [[FOR_COND_CLEANUP30:%.*]] 397; CGSCC: for.cond.cleanup30: 398; CGSCC-NEXT: br label [[FOR_END38:%.*]] 399; CGSCC: for.body31: 400; CGSCC-NEXT: [[ARRAYIDX33:%.*]] = getelementptr inbounds [1024 x i8], ptr [[BYTES]], i64 0, i64 [[INDVARS_IV12]] 401; CGSCC-NEXT: [[I23:%.*]] = load i8, ptr [[ARRAYIDX33]], align 1, !tbaa [[TBAA15]] 402; CGSCC-NEXT: [[ARRAYIDX35:%.*]] = getelementptr inbounds [1024 x i8], ptr @globalBytes, i64 0, i64 [[INDVARS_IV12]] 403; CGSCC-NEXT: store i8 [[I23]], ptr [[ARRAYIDX35]], align 1, !tbaa [[TBAA15]] 404; CGSCC-NEXT: br label [[FOR_INC36]] 405; CGSCC: for.inc36: 406; CGSCC-NEXT: [[INDVARS_IV_NEXT13]] = add nuw nsw i64 [[INDVARS_IV12]], 1 407; CGSCC-NEXT: br label [[FOR_COND28]], !llvm.loop [[LOOP23:![0-9]+]] 408; CGSCC: for.end38: 409; CGSCC-NEXT: call void @llvm.lifetime.end.p0(i64 noundef 1024, ptr noalias nofree noundef nonnull align 16 captures(none) dereferenceable(1024) [[BYTES]]) #[[ATTR20]] 410; CGSCC-NEXT: ret void 411; 412entry: 413 %Bytes = alloca [1024 x i8], align 16 414 call void @llvm.lifetime.start.p0(i64 1024, ptr nonnull %Bytes) 415 br label %for.cond 416 417for.cond: ; preds = %for.inc, %entry 418 %indvars.iv = phi i64 [ %indvars.iv.next, %for.inc ], [ 0, %entry ] 419 %exitcond = icmp ne i64 %indvars.iv, 100 420 br i1 %exitcond, label %for.body, label %for.cond.cleanup 421 422for.cond.cleanup: ; preds = %for.cond 423 br label %for.end 424 425for.body: ; preds = %for.cond 426 %i15 = mul nuw nsw i64 %indvars.iv, 10 427 %arrayidx = getelementptr inbounds [1024 x i8], ptr %Bytes, i64 0, i64 %i15 428 store i8 0, ptr %arrayidx, align 2, !tbaa !15 429 br label %for.inc 430 431for.inc: ; preds = %for.body 432 %indvars.iv.next = add nuw nsw i64 %indvars.iv, 1 433 br label %for.cond, !llvm.loop !16 434 435for.end: ; preds = %for.cond.cleanup 436 br label %for.cond2 437 438for.cond2: ; preds = %for.inc9, %for.end 439 %indvars.iv2 = phi i64 [ %indvars.iv.next3, %for.inc9 ], [ 0, %for.end ] 440 %exitcond6 = icmp ne i64 %indvars.iv2, 10 441 br i1 %exitcond6, label %for.body5, label %for.cond.cleanup4 442 443for.cond.cleanup4: ; preds = %for.cond2 444 br label %for.end11 445 446for.body5: ; preds = %for.cond2 447 %i17 = mul nuw nsw i64 %indvars.iv2, 10 448 %i18 = or i64 %i17, 1 449 %arrayidx8 = getelementptr inbounds float, ptr %Bytes, i64 %i18 450 store float 0.000000e+00, ptr %arrayidx8, align 4, !tbaa !18 451 br label %for.inc9 452 453for.inc9: ; preds = %for.body5 454 %indvars.iv.next3 = add nuw nsw i64 %indvars.iv2, 1 455 br label %for.cond2, !llvm.loop !19 456 457for.end11: ; preds = %for.cond.cleanup4 458 br label %for.cond13 459 460for.cond13: ; preds = %for.inc22, %for.end11 461 %indvars.iv7 = phi i64 [ %indvars.iv.next8, %for.inc22 ], [ 0, %for.end11 ] 462 %exitcond11 = icmp ne i64 %indvars.iv7, 20 463 br i1 %exitcond11, label %for.body16, label %for.cond.cleanup15 464 465for.cond.cleanup15: ; preds = %for.cond13 466 br label %for.end24 467 468for.body16: ; preds = %for.cond13 469 %i20 = mul nuw nsw i64 %indvars.iv7, 10 470 %i21 = add nuw nsw i64 %i20, 2 471 %arrayidx21 = getelementptr inbounds i64, ptr %Bytes, i64 %i21 472 store i64 0, ptr %arrayidx21, align 16, !tbaa !20 473 br label %for.inc22 474 475for.inc22: ; preds = %for.body16 476 %indvars.iv.next8 = add nuw nsw i64 %indvars.iv7, 1 477 br label %for.cond13, !llvm.loop !22 478 479for.end24: ; preds = %for.cond.cleanup15 480 %arrayidx25 = getelementptr inbounds [1024 x i8], ptr %Bytes, i64 0, i64 1023 481 store i8 0, ptr %arrayidx25, align 1, !tbaa !15 482 %arrayidx26 = getelementptr inbounds [1024 x i8], ptr %Bytes, i64 0, i64 500 483 call void @write_arg(ptr nonnull %arrayidx26, i32 0) 484 br label %for.cond28 485 486for.cond28: ; preds = %for.inc36, %for.end24 487 %indvars.iv12 = phi i64 [ %indvars.iv.next13, %for.inc36 ], [ 0, %for.end24 ] 488 %exitcond14 = icmp ne i64 %indvars.iv12, 1024 489 br i1 %exitcond14, label %for.body31, label %for.cond.cleanup30 490 491for.cond.cleanup30: ; preds = %for.cond28 492 br label %for.end38 493 494for.body31: ; preds = %for.cond28 495 %arrayidx33 = getelementptr inbounds [1024 x i8], ptr %Bytes, i64 0, i64 %indvars.iv12 496 %i23 = load i8, ptr %arrayidx33, align 1, !tbaa !15 497 %arrayidx35 = getelementptr inbounds [1024 x i8], ptr @globalBytes, i64 0, i64 %indvars.iv12 498 store i8 %i23, ptr %arrayidx35, align 1, !tbaa !15 499 br label %for.inc36 500 501for.inc36: ; preds = %for.body31 502 %indvars.iv.next13 = add nuw nsw i64 %indvars.iv12, 1 503 br label %for.cond28, !llvm.loop !23 504 505for.end38: ; preds = %for.cond.cleanup30 506 call void @llvm.lifetime.end.p0(i64 1024, ptr nonnull %Bytes) 507 ret void 508} 509 510; int local_alloca_simplifiable_3() { 511; int A = 1; 512; // split 513; A = 2; 514; return A; 515; } 516; 517define i32 @local_alloca_simplifiable_3() { 518; CHECK: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none) 519; CHECK-LABEL: define {{[^@]+}}@local_alloca_simplifiable_3 520; CHECK-SAME: () #[[ATTR4:[0-9]+]] { 521; CHECK-NEXT: br label [[SPLIT:%.*]] 522; CHECK: split: 523; CHECK-NEXT: ret i32 2 524; 525 %A = alloca i32, align 4 526 store i32 1, ptr %A 527 br label %split 528split: 529 store i32 2, ptr %A 530 %l = load i32, ptr %A, align 4 531 ret i32 %l 532} 533; int local_alloca_simplifiable_4() { 534; int A; 535; return A; 536; } 537; 538define i32 @local_alloca_simplifiable_4() { 539; CHECK: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none) 540; CHECK-LABEL: define {{[^@]+}}@local_alloca_simplifiable_4 541; CHECK-SAME: () #[[ATTR4]] { 542; CHECK-NEXT: ret i32 undef 543; 544 %A = alloca i32, align 4 545 %l = load i32, ptr %A, align 4 546 ret i32 %l 547} 548 549; static int GI1 __attribute__((loader_uninitialized)); 550; int multi_obj_simplifiable_1(int cnd) { 551; int L = GI1 = 5; 552; int *p = cnd ? &GI1 : &L; 553; return *p; 554; } 555define i32 @multi_obj_simplifiable_1(i32 %cnd) { 556; TUNIT: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn 557; TUNIT-LABEL: define {{[^@]+}}@multi_obj_simplifiable_1 558; TUNIT-SAME: (i32 [[CND:%.*]]) #[[ATTR3]] { 559; TUNIT-NEXT: entry: 560; TUNIT-NEXT: [[L:%.*]] = alloca i32, align 4 561; TUNIT-NEXT: call void @llvm.lifetime.start.p0(i64 noundef 4, ptr noalias nofree noundef nonnull align 4 captures(none) dereferenceable(4) [[L]]) #[[ATTR17]] 562; TUNIT-NEXT: [[TOBOOL_NOT:%.*]] = icmp eq i32 [[CND]], 0 563; TUNIT-NEXT: br i1 [[TOBOOL_NOT]], label [[COND_FALSE:%.*]], label [[COND_TRUE:%.*]] 564; TUNIT: cond.true: 565; TUNIT-NEXT: br label [[COND_END:%.*]] 566; TUNIT: cond.false: 567; TUNIT-NEXT: br label [[COND_END]] 568; TUNIT: cond.end: 569; TUNIT-NEXT: call void @llvm.lifetime.end.p0(i64 noundef 4, ptr noalias nofree noundef nonnull align 4 captures(none) dereferenceable(4) [[L]]) #[[ATTR17]] 570; TUNIT-NEXT: ret i32 5 571; 572; CGSCC: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn 573; CGSCC-LABEL: define {{[^@]+}}@multi_obj_simplifiable_1 574; CGSCC-SAME: (i32 [[CND:%.*]]) #[[ATTR5:[0-9]+]] { 575; CGSCC-NEXT: entry: 576; CGSCC-NEXT: [[L:%.*]] = alloca i32, align 4 577; CGSCC-NEXT: call void @llvm.lifetime.start.p0(i64 noundef 4, ptr noalias nofree noundef nonnull align 4 captures(none) dereferenceable(4) [[L]]) #[[ATTR20]] 578; CGSCC-NEXT: [[TOBOOL_NOT:%.*]] = icmp eq i32 [[CND]], 0 579; CGSCC-NEXT: br i1 [[TOBOOL_NOT]], label [[COND_FALSE:%.*]], label [[COND_TRUE:%.*]] 580; CGSCC: cond.true: 581; CGSCC-NEXT: br label [[COND_END:%.*]] 582; CGSCC: cond.false: 583; CGSCC-NEXT: br label [[COND_END]] 584; CGSCC: cond.end: 585; CGSCC-NEXT: call void @llvm.lifetime.end.p0(i64 noundef 4, ptr noalias nofree noundef nonnull align 4 captures(none) dereferenceable(4) [[L]]) #[[ATTR20]] 586; CGSCC-NEXT: ret i32 5 587; 588entry: 589 %L = alloca i32, align 4 590 call void @llvm.lifetime.start.p0(i64 4, ptr nonnull %L) 591 store i32 5, ptr @GI1, align 4, !tbaa !3 592 store i32 5, ptr %L, align 4, !tbaa !3 593 %tobool.not = icmp eq i32 %cnd, 0 594 br i1 %tobool.not, label %cond.false, label %cond.true 595 596cond.true: ; preds = %entry 597 br label %cond.end 598 599cond.false: ; preds = %entry 600 br label %cond.end 601 602cond.end: ; preds = %cond.false, %cond.true 603 %cond = phi ptr [ @GI1, %cond.true ], [ %L, %cond.false ] 604 %i1 = load i32, ptr %cond, align 4, !tbaa !3 605 call void @llvm.lifetime.end.p0(i64 4, ptr nonnull %L) 606 ret i32 %i1 607} 608 609; static int GI2 __attribute__((loader_uninitialized)); 610; int multi_obj_simplifiable_2(int cnd) { 611; int L; 612; int *p = cnd ? &GI2 : &L; 613; *p = 5; 614; return *p; 615; } 616; 617define i32 @multi_obj_simplifiable_2(i32 %cnd) { 618; TUNIT: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn 619; TUNIT-LABEL: define {{[^@]+}}@multi_obj_simplifiable_2 620; TUNIT-SAME: (i32 [[CND:%.*]]) #[[ATTR3]] { 621; TUNIT-NEXT: entry: 622; TUNIT-NEXT: [[L:%.*]] = alloca i32, align 4 623; TUNIT-NEXT: call void @llvm.lifetime.start.p0(i64 noundef 4, ptr noalias nofree noundef nonnull align 4 captures(none) dereferenceable(4) [[L]]) #[[ATTR17]] 624; TUNIT-NEXT: [[TOBOOL_NOT:%.*]] = icmp eq i32 [[CND]], 0 625; TUNIT-NEXT: br i1 [[TOBOOL_NOT]], label [[COND_FALSE:%.*]], label [[COND_TRUE:%.*]] 626; TUNIT: cond.true: 627; TUNIT-NEXT: br label [[COND_END:%.*]] 628; TUNIT: cond.false: 629; TUNIT-NEXT: br label [[COND_END]] 630; TUNIT: cond.end: 631; TUNIT-NEXT: call void @llvm.lifetime.end.p0(i64 noundef 4, ptr noalias nofree noundef nonnull align 4 captures(none) dereferenceable(4) [[L]]) #[[ATTR17]] 632; TUNIT-NEXT: ret i32 5 633; 634; CGSCC: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn 635; CGSCC-LABEL: define {{[^@]+}}@multi_obj_simplifiable_2 636; CGSCC-SAME: (i32 [[CND:%.*]]) #[[ATTR5]] { 637; CGSCC-NEXT: entry: 638; CGSCC-NEXT: [[L:%.*]] = alloca i32, align 4 639; CGSCC-NEXT: call void @llvm.lifetime.start.p0(i64 noundef 4, ptr noalias nofree noundef nonnull align 4 captures(none) dereferenceable(4) [[L]]) #[[ATTR20]] 640; CGSCC-NEXT: [[TOBOOL_NOT:%.*]] = icmp eq i32 [[CND]], 0 641; CGSCC-NEXT: br i1 [[TOBOOL_NOT]], label [[COND_FALSE:%.*]], label [[COND_TRUE:%.*]] 642; CGSCC: cond.true: 643; CGSCC-NEXT: br label [[COND_END:%.*]] 644; CGSCC: cond.false: 645; CGSCC-NEXT: br label [[COND_END]] 646; CGSCC: cond.end: 647; CGSCC-NEXT: call void @llvm.lifetime.end.p0(i64 noundef 4, ptr noalias nofree noundef nonnull align 4 captures(none) dereferenceable(4) [[L]]) #[[ATTR20]] 648; CGSCC-NEXT: ret i32 5 649; 650entry: 651 %L = alloca i32, align 4 652 call void @llvm.lifetime.start.p0(i64 4, ptr nonnull %L) 653 %tobool.not = icmp eq i32 %cnd, 0 654 br i1 %tobool.not, label %cond.false, label %cond.true 655 656cond.true: ; preds = %entry 657 br label %cond.end 658 659cond.false: ; preds = %entry 660 br label %cond.end 661 662cond.end: ; preds = %cond.false, %cond.true 663 %cond = phi ptr [ @GI2, %cond.true ], [ %L, %cond.false ] 664 store i32 5, ptr %cond, align 4, !tbaa !3 665 %l = load i32, ptr %cond, align 4, !tbaa !3 666 call void @llvm.lifetime.end.p0(i64 4, ptr nonnull %L) 667 ret i32 %l 668} 669 670; static struct S Gs __attribute__((loader_uninitialized)); 671; struct S static_global_simplifiable_1(void) { 672; Gs.f1 = 1.1; 673; Gs.f2 = 2.2; 674; Gs.f3 = 3.3; 675; write_arg(&Gs.i1, 1); 676; write_arg(&Gs.i2, 2); 677; write_arg(&Gs.i3, 3); 678; struct S r; 679; r.f1 = Gs.f1; 680; r.f2 = Gs.f2 * 2; 681; r.f3 = Gs.f3 + Gs.f1; 682; r.i1 = Gs.i1; 683; r.i2 = Gs.i2 * 2; 684; r.i3 = Gs.i3 + Gs.i1; 685; return r; 686; } 687; 688define void @static_global_simplifiable_1(ptr noalias sret(%struct.S) align 4 %agg.result) { 689; TUNIT: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(write) 690; TUNIT-LABEL: define {{[^@]+}}@static_global_simplifiable_1 691; TUNIT-SAME: (ptr noalias nofree writeonly sret([[STRUCT_S:%.*]]) align 4 captures(none) dereferenceable_or_null(24) [[AGG_RESULT:%.*]]) #[[ATTR5:[0-9]+]] { 692; TUNIT-NEXT: entry: 693; TUNIT-NEXT: call void @write_arg(ptr nofree noundef nonnull writeonly align 4 captures(none) dereferenceable(24) @Gs1, i32 noundef 1) #[[ATTR18]] 694; TUNIT-NEXT: call void @write_arg(ptr nofree noundef nonnull writeonly align 4 captures(none) dereferenceable(20) getelementptr inbounds ([[STRUCT_S]], ptr @Gs1, i64 0, i32 1), i32 noundef 2) #[[ATTR18]] 695; TUNIT-NEXT: call void @write_arg(ptr nofree noundef nonnull writeonly align 4 captures(none) dereferenceable(16) getelementptr inbounds ([[STRUCT_S]], ptr @Gs1, i64 0, i32 2), i32 noundef 3) #[[ATTR18]] 696; TUNIT-NEXT: [[F1:%.*]] = getelementptr inbounds [[STRUCT_S]], ptr [[AGG_RESULT]], i64 0, i32 3 697; TUNIT-NEXT: store float 0x3FF19999A0000000, ptr [[F1]], align 4, !tbaa [[TBAA7]] 698; TUNIT-NEXT: [[F2:%.*]] = getelementptr inbounds [[STRUCT_S]], ptr [[AGG_RESULT]], i64 0, i32 4 699; TUNIT-NEXT: store float 0x40119999A0000000, ptr [[F2]], align 4, !tbaa [[TBAA10]] 700; TUNIT-NEXT: [[F3:%.*]] = getelementptr inbounds [[STRUCT_S]], ptr [[AGG_RESULT]], i64 0, i32 5 701; TUNIT-NEXT: store float 0x40119999A0000000, ptr [[F3]], align 4, !tbaa [[TBAA11]] 702; TUNIT-NEXT: store i32 1, ptr [[AGG_RESULT]], align 4, !tbaa [[TBAA12]] 703; TUNIT-NEXT: [[I2:%.*]] = getelementptr inbounds [[STRUCT_S]], ptr [[AGG_RESULT]], i64 0, i32 1 704; TUNIT-NEXT: store i32 4, ptr [[I2]], align 4, !tbaa [[TBAA13]] 705; TUNIT-NEXT: [[I3:%.*]] = getelementptr inbounds [[STRUCT_S]], ptr [[AGG_RESULT]], i64 0, i32 2 706; TUNIT-NEXT: store i32 4, ptr [[I3]], align 4, !tbaa [[TBAA14]] 707; TUNIT-NEXT: ret void 708; 709; CGSCC: Function Attrs: mustprogress nofree nosync nounwind willreturn 710; CGSCC-LABEL: define {{[^@]+}}@static_global_simplifiable_1 711; CGSCC-SAME: (ptr noalias nofree noundef nonnull writeonly sret([[STRUCT_S:%.*]]) align 4 captures(none) dereferenceable(24) [[AGG_RESULT:%.*]]) #[[ATTR3]] { 712; CGSCC-NEXT: entry: 713; CGSCC-NEXT: store float 0x3FF19999A0000000, ptr getelementptr inbounds ([[STRUCT_S]], ptr @Gs1, i64 0, i32 3), align 4, !tbaa [[TBAA7]] 714; CGSCC-NEXT: store float 0x40019999A0000000, ptr getelementptr inbounds ([[STRUCT_S]], ptr @Gs1, i64 0, i32 4), align 4, !tbaa [[TBAA10]] 715; CGSCC-NEXT: store float 0x400A666660000000, ptr getelementptr inbounds ([[STRUCT_S]], ptr @Gs1, i64 0, i32 5), align 4, !tbaa [[TBAA11]] 716; CGSCC-NEXT: call void @write_arg(ptr nofree noundef nonnull writeonly align 4 captures(none) dereferenceable(24) @Gs1, i32 noundef 1) #[[ATTR21]] 717; CGSCC-NEXT: call void @write_arg(ptr nofree noundef nonnull writeonly align 4 captures(none) dereferenceable(20) getelementptr inbounds ([[STRUCT_S]], ptr @Gs1, i64 0, i32 1), i32 noundef 2) #[[ATTR21]] 718; CGSCC-NEXT: call void @write_arg(ptr nofree noundef nonnull writeonly align 4 captures(none) dereferenceable(16) getelementptr inbounds ([[STRUCT_S]], ptr @Gs1, i64 0, i32 2), i32 noundef 3) #[[ATTR21]] 719; CGSCC-NEXT: [[I:%.*]] = load float, ptr getelementptr inbounds ([[STRUCT_S]], ptr @Gs1, i64 0, i32 3), align 4, !tbaa [[TBAA7]] 720; CGSCC-NEXT: [[F1:%.*]] = getelementptr inbounds [[STRUCT_S]], ptr [[AGG_RESULT]], i64 0, i32 3 721; CGSCC-NEXT: store float [[I]], ptr [[F1]], align 4, !tbaa [[TBAA7]] 722; CGSCC-NEXT: [[I4:%.*]] = load float, ptr getelementptr inbounds ([[STRUCT_S]], ptr @Gs1, i64 0, i32 4), align 4, !tbaa [[TBAA10]] 723; CGSCC-NEXT: [[MUL:%.*]] = fmul float [[I4]], 2.000000e+00 724; CGSCC-NEXT: [[F2:%.*]] = getelementptr inbounds [[STRUCT_S]], ptr [[AGG_RESULT]], i64 0, i32 4 725; CGSCC-NEXT: store float [[MUL]], ptr [[F2]], align 4, !tbaa [[TBAA10]] 726; CGSCC-NEXT: [[I5:%.*]] = load float, ptr getelementptr inbounds ([[STRUCT_S]], ptr @Gs1, i64 0, i32 5), align 4, !tbaa [[TBAA11]] 727; CGSCC-NEXT: [[I6:%.*]] = load float, ptr getelementptr inbounds ([[STRUCT_S]], ptr @Gs1, i64 0, i32 3), align 4, !tbaa [[TBAA7]] 728; CGSCC-NEXT: [[ADD:%.*]] = fadd float [[I5]], [[I6]] 729; CGSCC-NEXT: [[F3:%.*]] = getelementptr inbounds [[STRUCT_S]], ptr [[AGG_RESULT]], i64 0, i32 5 730; CGSCC-NEXT: store float [[ADD]], ptr [[F3]], align 4, !tbaa [[TBAA11]] 731; CGSCC-NEXT: [[I7:%.*]] = load i32, ptr @Gs1, align 4, !tbaa [[TBAA12]] 732; CGSCC-NEXT: store i32 [[I7]], ptr [[AGG_RESULT]], align 4, !tbaa [[TBAA12]] 733; CGSCC-NEXT: [[I8:%.*]] = load i32, ptr getelementptr inbounds ([[STRUCT_S]], ptr @Gs1, i64 0, i32 1), align 4, !tbaa [[TBAA13]] 734; CGSCC-NEXT: [[MUL1:%.*]] = shl nsw i32 [[I8]], 1 735; CGSCC-NEXT: [[I2:%.*]] = getelementptr inbounds [[STRUCT_S]], ptr [[AGG_RESULT]], i64 0, i32 1 736; CGSCC-NEXT: store i32 [[MUL1]], ptr [[I2]], align 4, !tbaa [[TBAA13]] 737; CGSCC-NEXT: [[I9:%.*]] = load i32, ptr getelementptr inbounds ([[STRUCT_S]], ptr @Gs1, i64 0, i32 2), align 4, !tbaa [[TBAA14]] 738; CGSCC-NEXT: [[I10:%.*]] = load i32, ptr @Gs1, align 4, !tbaa [[TBAA12]] 739; CGSCC-NEXT: [[ADD2:%.*]] = add nsw i32 [[I9]], [[I10]] 740; CGSCC-NEXT: [[I3:%.*]] = getelementptr inbounds [[STRUCT_S]], ptr [[AGG_RESULT]], i64 0, i32 2 741; CGSCC-NEXT: store i32 [[ADD2]], ptr [[I3]], align 4, !tbaa [[TBAA14]] 742; CGSCC-NEXT: ret void 743; 744entry: 745 store float 0x3FF19999A0000000, ptr getelementptr inbounds (%struct.S, ptr @Gs1, i64 0, i32 3), align 4, !tbaa !7 746 store float 0x40019999A0000000, ptr getelementptr inbounds (%struct.S, ptr @Gs1, i64 0, i32 4), align 4, !tbaa !10 747 store float 0x400A666660000000, ptr getelementptr inbounds (%struct.S, ptr @Gs1, i64 0, i32 5), align 4, !tbaa !11 748 call void @write_arg(ptr @Gs1, i32 1) 749 call void @write_arg(ptr getelementptr inbounds (%struct.S, ptr @Gs1, i64 0, i32 1), i32 2) 750 call void @write_arg(ptr getelementptr inbounds (%struct.S, ptr @Gs1, i64 0, i32 2), i32 3) 751 %i = load float, ptr getelementptr inbounds (%struct.S, ptr @Gs1, i64 0, i32 3), align 4, !tbaa !7 752 %f1 = getelementptr inbounds %struct.S, ptr %agg.result, i64 0, i32 3 753 store float %i, ptr %f1, align 4, !tbaa !7 754 %i4 = load float, ptr getelementptr inbounds (%struct.S, ptr @Gs1, i64 0, i32 4), align 4, !tbaa !10 755 %mul = fmul float %i4, 2.000000e+00 756 %f2 = getelementptr inbounds %struct.S, ptr %agg.result, i64 0, i32 4 757 store float %mul, ptr %f2, align 4, !tbaa !10 758 %i5 = load float, ptr getelementptr inbounds (%struct.S, ptr @Gs1, i64 0, i32 5), align 4, !tbaa !11 759 %i6 = load float, ptr getelementptr inbounds (%struct.S, ptr @Gs1, i64 0, i32 3), align 4, !tbaa !7 760 %add = fadd float %i5, %i6 761 %f3 = getelementptr inbounds %struct.S, ptr %agg.result, i64 0, i32 5 762 store float %add, ptr %f3, align 4, !tbaa !11 763 %i7 = load i32, ptr @Gs1, align 4, !tbaa !12 764 store i32 %i7, ptr %agg.result, align 4, !tbaa !12 765 %i8 = load i32, ptr getelementptr inbounds (%struct.S, ptr @Gs1, i64 0, i32 1), align 4, !tbaa !13 766 %mul1 = shl nsw i32 %i8, 1 767 %i2 = getelementptr inbounds %struct.S, ptr %agg.result, i64 0, i32 1 768 store i32 %mul1, ptr %i2, align 4, !tbaa !13 769 %i9 = load i32, ptr getelementptr inbounds (%struct.S, ptr @Gs1, i64 0, i32 2), align 4, !tbaa !14 770 %i10 = load i32, ptr @Gs1, align 4, !tbaa !12 771 %add2 = add nsw i32 %i9, %i10 772 %i3 = getelementptr inbounds %struct.S, ptr %agg.result, i64 0, i32 2 773 store i32 %add2, ptr %i3, align 4, !tbaa !14 774 ret void 775} 776 777define i32 @test_range_merge1() { 778; TUNIT: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(write) 779; TUNIT-LABEL: define {{[^@]+}}@test_range_merge1 780; TUNIT-SAME: () #[[ATTR5]] { 781; TUNIT-NEXT: ret i32 2 782; 783; CGSCC: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(write) 784; CGSCC-LABEL: define {{[^@]+}}@test_range_merge1 785; CGSCC-SAME: () #[[ATTR6:[0-9]+]] { 786; CGSCC-NEXT: ret i32 2 787; 788 store <2 x i32> <i32 1, i32 1>, ptr @Vs1 789 store float 2.000000e+00, ptr getelementptr inbounds (%struct.S, ptr @Vs1, i64 0, i32 4) 790 %l0 = load i32, ptr @Vs1 791 %l1 = load i32, ptr getelementptr inbounds (%struct.S, ptr @Vs1, i64 0, i32 1) 792 %add = add i32 %l0, %l1 793 ret i32 %add 794} 795 796define i32 @test_range_merge2() { 797; TUNIT: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn 798; TUNIT-LABEL: define {{[^@]+}}@test_range_merge2 799; TUNIT-SAME: () #[[ATTR3]] { 800; TUNIT-NEXT: store <2 x i32> <i32 3, i32 4>, ptr @Vs2, align 8 801; TUNIT-NEXT: [[L0:%.*]] = load i32, ptr @Vs2, align 4 802; TUNIT-NEXT: [[L1:%.*]] = load i32, ptr getelementptr inbounds ([[STRUCT_S:%.*]], ptr @Vs2, i64 0, i32 1), align 4 803; TUNIT-NEXT: [[ADD:%.*]] = add i32 [[L0]], [[L1]] 804; TUNIT-NEXT: ret i32 [[ADD]] 805; 806; CGSCC: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn 807; CGSCC-LABEL: define {{[^@]+}}@test_range_merge2 808; CGSCC-SAME: () #[[ATTR5]] { 809; CGSCC-NEXT: store <2 x i32> <i32 3, i32 4>, ptr @Vs2, align 8 810; CGSCC-NEXT: [[L0:%.*]] = load i32, ptr @Vs2, align 4 811; CGSCC-NEXT: [[L1:%.*]] = load i32, ptr getelementptr inbounds ([[STRUCT_S:%.*]], ptr @Vs2, i64 0, i32 1), align 4 812; CGSCC-NEXT: [[ADD:%.*]] = add i32 [[L0]], [[L1]] 813; CGSCC-NEXT: ret i32 [[ADD]] 814; 815 store <2 x i32> <i32 3, i32 4>, ptr @Vs2 816 store float 2.000000e+00, ptr getelementptr inbounds (%struct.S, ptr @Vs2, i64 0, i32 4) 817 %l0 = load i32, ptr @Vs2 818 %l1 = load i32, ptr getelementptr inbounds (%struct.S, ptr @Vs2, i64 0, i32 1) 819 %add = add i32 %l0, %l1 820 ret i32 %add 821} 822 823; static char GBytes[1024]; 824; void static_global_simplifiable_2(void) { 825; for (int i = 0; i < 100; ++i) 826; GBytes[i * 10] = 0; 827; for (int i = 0; i < 10; ++i) 828; ((float *)GBytes)[i * 10 + 1] = 0; 829; for (int i = 0; i < 20; ++i) 830; ((long long int *)GBytes)[i * 10 + 2] = 0; 831; GBytes[1023] = 0; 832; write_arg((int *)&GBytes[500], 0); 833; struct S R; 834; for (int i = 0; i < 1024; ++i) 835; globalBytes[i] = GBytes[i]; 836; } 837; 838define void @static_global_simplifiable_2() { 839; TUNIT: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(write) 840; TUNIT-LABEL: define {{[^@]+}}@static_global_simplifiable_2 841; TUNIT-SAME: () #[[ATTR5]] { 842; TUNIT-NEXT: entry: 843; TUNIT-NEXT: br label [[FOR_COND:%.*]] 844; TUNIT: for.cond: 845; TUNIT-NEXT: [[INDVARS_IV:%.*]] = phi i64 [ [[INDVARS_IV_NEXT:%.*]], [[FOR_INC:%.*]] ], [ 0, [[ENTRY:%.*]] ] 846; TUNIT-NEXT: [[EXITCOND:%.*]] = icmp ne i64 [[INDVARS_IV]], 100 847; TUNIT-NEXT: br i1 [[EXITCOND]], label [[FOR_BODY:%.*]], label [[FOR_COND_CLEANUP:%.*]] 848; TUNIT: for.cond.cleanup: 849; TUNIT-NEXT: br label [[FOR_END:%.*]] 850; TUNIT: for.body: 851; TUNIT-NEXT: [[I:%.*]] = mul nuw nsw i64 [[INDVARS_IV]], 10 852; TUNIT-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds [1024 x i8], ptr @GBytes, i64 0, i64 [[I]] 853; TUNIT-NEXT: br label [[FOR_INC]] 854; TUNIT: for.inc: 855; TUNIT-NEXT: [[INDVARS_IV_NEXT]] = add nuw nsw i64 [[INDVARS_IV]], 1 856; TUNIT-NEXT: br label [[FOR_COND]], !llvm.loop [[LOOP21:![0-9]+]] 857; TUNIT: for.end: 858; TUNIT-NEXT: br label [[FOR_COND2:%.*]] 859; TUNIT: for.cond2: 860; TUNIT-NEXT: [[INDVARS_IV2:%.*]] = phi i64 [ [[INDVARS_IV_NEXT3:%.*]], [[FOR_INC9:%.*]] ], [ 0, [[FOR_END]] ] 861; TUNIT-NEXT: [[EXITCOND6:%.*]] = icmp ne i64 [[INDVARS_IV2]], 10 862; TUNIT-NEXT: br i1 [[EXITCOND6]], label [[FOR_BODY5:%.*]], label [[FOR_COND_CLEANUP4:%.*]] 863; TUNIT: for.cond.cleanup4: 864; TUNIT-NEXT: br label [[FOR_END11:%.*]] 865; TUNIT: for.body5: 866; TUNIT-NEXT: [[I15:%.*]] = mul nuw nsw i64 [[INDVARS_IV2]], 10 867; TUNIT-NEXT: [[I16:%.*]] = or i64 [[I15]], 1 868; TUNIT-NEXT: [[ARRAYIDX8:%.*]] = getelementptr inbounds float, ptr @GBytes, i64 [[I16]] 869; TUNIT-NEXT: br label [[FOR_INC9]] 870; TUNIT: for.inc9: 871; TUNIT-NEXT: [[INDVARS_IV_NEXT3]] = add nuw nsw i64 [[INDVARS_IV2]], 1 872; TUNIT-NEXT: br label [[FOR_COND2]], !llvm.loop [[LOOP22:![0-9]+]] 873; TUNIT: for.end11: 874; TUNIT-NEXT: br label [[FOR_COND13:%.*]] 875; TUNIT: for.cond13: 876; TUNIT-NEXT: [[INDVARS_IV7:%.*]] = phi i64 [ [[INDVARS_IV_NEXT8:%.*]], [[FOR_INC21:%.*]] ], [ 0, [[FOR_END11]] ] 877; TUNIT-NEXT: [[EXITCOND11:%.*]] = icmp ne i64 [[INDVARS_IV7]], 20 878; TUNIT-NEXT: br i1 [[EXITCOND11]], label [[FOR_BODY16:%.*]], label [[FOR_COND_CLEANUP15:%.*]] 879; TUNIT: for.cond.cleanup15: 880; TUNIT-NEXT: br label [[FOR_END23:%.*]] 881; TUNIT: for.body16: 882; TUNIT-NEXT: [[I17:%.*]] = mul nuw nsw i64 [[INDVARS_IV7]], 10 883; TUNIT-NEXT: [[I18:%.*]] = add nuw nsw i64 [[I17]], 2 884; TUNIT-NEXT: [[ARRAYIDX20:%.*]] = getelementptr inbounds i64, ptr @GBytes, i64 [[I18]] 885; TUNIT-NEXT: br label [[FOR_INC21]] 886; TUNIT: for.inc21: 887; TUNIT-NEXT: [[INDVARS_IV_NEXT8]] = add nuw nsw i64 [[INDVARS_IV7]], 1 888; TUNIT-NEXT: br label [[FOR_COND13]], !llvm.loop [[LOOP23:![0-9]+]] 889; TUNIT: for.end23: 890; TUNIT-NEXT: call void @write_arg(ptr nofree noundef nonnull writeonly align 4 captures(none) dereferenceable(524) getelementptr inbounds ([1024 x i8], ptr @GBytes, i64 0, i64 500), i32 noundef 0) #[[ATTR18]] 891; TUNIT-NEXT: br label [[FOR_COND25:%.*]] 892; TUNIT: for.cond25: 893; TUNIT-NEXT: [[INDVARS_IV12:%.*]] = phi i64 [ [[INDVARS_IV_NEXT13:%.*]], [[FOR_INC33:%.*]] ], [ 0, [[FOR_END23]] ] 894; TUNIT-NEXT: [[EXITCOND14:%.*]] = icmp ne i64 [[INDVARS_IV12]], 1024 895; TUNIT-NEXT: br i1 [[EXITCOND14]], label [[FOR_BODY28:%.*]], label [[FOR_COND_CLEANUP27:%.*]] 896; TUNIT: for.cond.cleanup27: 897; TUNIT-NEXT: br label [[FOR_END35:%.*]] 898; TUNIT: for.body28: 899; TUNIT-NEXT: [[ARRAYIDX32:%.*]] = getelementptr inbounds [1024 x i8], ptr @globalBytes, i64 0, i64 [[INDVARS_IV12]] 900; TUNIT-NEXT: store i8 0, ptr [[ARRAYIDX32]], align 1, !tbaa [[TBAA19]] 901; TUNIT-NEXT: br label [[FOR_INC33]] 902; TUNIT: for.inc33: 903; TUNIT-NEXT: [[INDVARS_IV_NEXT13]] = add nuw nsw i64 [[INDVARS_IV12]], 1 904; TUNIT-NEXT: br label [[FOR_COND25]], !llvm.loop [[LOOP24:![0-9]+]] 905; TUNIT: for.end35: 906; TUNIT-NEXT: ret void 907; 908; CGSCC: Function Attrs: mustprogress nofree nosync nounwind willreturn 909; CGSCC-LABEL: define {{[^@]+}}@static_global_simplifiable_2 910; CGSCC-SAME: () #[[ATTR3]] { 911; CGSCC-NEXT: entry: 912; CGSCC-NEXT: br label [[FOR_COND:%.*]] 913; CGSCC: for.cond: 914; CGSCC-NEXT: [[INDVARS_IV:%.*]] = phi i64 [ [[INDVARS_IV_NEXT:%.*]], [[FOR_INC:%.*]] ], [ 0, [[ENTRY:%.*]] ] 915; CGSCC-NEXT: [[EXITCOND:%.*]] = icmp ne i64 [[INDVARS_IV]], 100 916; CGSCC-NEXT: br i1 [[EXITCOND]], label [[FOR_BODY:%.*]], label [[FOR_COND_CLEANUP:%.*]] 917; CGSCC: for.cond.cleanup: 918; CGSCC-NEXT: br label [[FOR_END:%.*]] 919; CGSCC: for.body: 920; CGSCC-NEXT: [[I:%.*]] = mul nuw nsw i64 [[INDVARS_IV]], 10 921; CGSCC-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds [1024 x i8], ptr @GBytes, i64 0, i64 [[I]] 922; CGSCC-NEXT: store i8 0, ptr [[ARRAYIDX]], align 2, !tbaa [[TBAA15]] 923; CGSCC-NEXT: br label [[FOR_INC]] 924; CGSCC: for.inc: 925; CGSCC-NEXT: [[INDVARS_IV_NEXT]] = add nuw nsw i64 [[INDVARS_IV]], 1 926; CGSCC-NEXT: br label [[FOR_COND]], !llvm.loop [[LOOP24:![0-9]+]] 927; CGSCC: for.end: 928; CGSCC-NEXT: br label [[FOR_COND2:%.*]] 929; CGSCC: for.cond2: 930; CGSCC-NEXT: [[INDVARS_IV2:%.*]] = phi i64 [ [[INDVARS_IV_NEXT3:%.*]], [[FOR_INC9:%.*]] ], [ 0, [[FOR_END]] ] 931; CGSCC-NEXT: [[EXITCOND6:%.*]] = icmp ne i64 [[INDVARS_IV2]], 10 932; CGSCC-NEXT: br i1 [[EXITCOND6]], label [[FOR_BODY5:%.*]], label [[FOR_COND_CLEANUP4:%.*]] 933; CGSCC: for.cond.cleanup4: 934; CGSCC-NEXT: br label [[FOR_END11:%.*]] 935; CGSCC: for.body5: 936; CGSCC-NEXT: [[I15:%.*]] = mul nuw nsw i64 [[INDVARS_IV2]], 10 937; CGSCC-NEXT: [[I16:%.*]] = or i64 [[I15]], 1 938; CGSCC-NEXT: [[ARRAYIDX8:%.*]] = getelementptr inbounds float, ptr @GBytes, i64 [[I16]] 939; CGSCC-NEXT: store float 0.000000e+00, ptr [[ARRAYIDX8]], align 4, !tbaa [[TBAA18]] 940; CGSCC-NEXT: br label [[FOR_INC9]] 941; CGSCC: for.inc9: 942; CGSCC-NEXT: [[INDVARS_IV_NEXT3]] = add nuw nsw i64 [[INDVARS_IV2]], 1 943; CGSCC-NEXT: br label [[FOR_COND2]], !llvm.loop [[LOOP25:![0-9]+]] 944; CGSCC: for.end11: 945; CGSCC-NEXT: br label [[FOR_COND13:%.*]] 946; CGSCC: for.cond13: 947; CGSCC-NEXT: [[INDVARS_IV7:%.*]] = phi i64 [ [[INDVARS_IV_NEXT8:%.*]], [[FOR_INC21:%.*]] ], [ 0, [[FOR_END11]] ] 948; CGSCC-NEXT: [[EXITCOND11:%.*]] = icmp ne i64 [[INDVARS_IV7]], 20 949; CGSCC-NEXT: br i1 [[EXITCOND11]], label [[FOR_BODY16:%.*]], label [[FOR_COND_CLEANUP15:%.*]] 950; CGSCC: for.cond.cleanup15: 951; CGSCC-NEXT: br label [[FOR_END23:%.*]] 952; CGSCC: for.body16: 953; CGSCC-NEXT: [[I17:%.*]] = mul nuw nsw i64 [[INDVARS_IV7]], 10 954; CGSCC-NEXT: [[I18:%.*]] = add nuw nsw i64 [[I17]], 2 955; CGSCC-NEXT: [[ARRAYIDX20:%.*]] = getelementptr inbounds i64, ptr @GBytes, i64 [[I18]] 956; CGSCC-NEXT: store i64 0, ptr [[ARRAYIDX20]], align 16, !tbaa [[TBAA20]] 957; CGSCC-NEXT: br label [[FOR_INC21]] 958; CGSCC: for.inc21: 959; CGSCC-NEXT: [[INDVARS_IV_NEXT8]] = add nuw nsw i64 [[INDVARS_IV7]], 1 960; CGSCC-NEXT: br label [[FOR_COND13]], !llvm.loop [[LOOP26:![0-9]+]] 961; CGSCC: for.end23: 962; CGSCC-NEXT: store i8 0, ptr getelementptr inbounds ([1024 x i8], ptr @GBytes, i64 0, i64 1023), align 1, !tbaa [[TBAA15]] 963; CGSCC-NEXT: call void @write_arg(ptr nofree noundef nonnull writeonly align 4 captures(none) dereferenceable(524) getelementptr inbounds ([1024 x i8], ptr @GBytes, i64 0, i64 500), i32 noundef 0) #[[ATTR21]] 964; CGSCC-NEXT: br label [[FOR_COND25:%.*]] 965; CGSCC: for.cond25: 966; CGSCC-NEXT: [[INDVARS_IV12:%.*]] = phi i64 [ [[INDVARS_IV_NEXT13:%.*]], [[FOR_INC33:%.*]] ], [ 0, [[FOR_END23]] ] 967; CGSCC-NEXT: [[EXITCOND14:%.*]] = icmp ne i64 [[INDVARS_IV12]], 1024 968; CGSCC-NEXT: br i1 [[EXITCOND14]], label [[FOR_BODY28:%.*]], label [[FOR_COND_CLEANUP27:%.*]] 969; CGSCC: for.cond.cleanup27: 970; CGSCC-NEXT: br label [[FOR_END35:%.*]] 971; CGSCC: for.body28: 972; CGSCC-NEXT: [[ARRAYIDX30:%.*]] = getelementptr inbounds [1024 x i8], ptr @GBytes, i64 0, i64 [[INDVARS_IV12]] 973; CGSCC-NEXT: [[I19:%.*]] = load i8, ptr [[ARRAYIDX30]], align 1, !tbaa [[TBAA15]] 974; CGSCC-NEXT: [[ARRAYIDX32:%.*]] = getelementptr inbounds [1024 x i8], ptr @globalBytes, i64 0, i64 [[INDVARS_IV12]] 975; CGSCC-NEXT: store i8 [[I19]], ptr [[ARRAYIDX32]], align 1, !tbaa [[TBAA15]] 976; CGSCC-NEXT: br label [[FOR_INC33]] 977; CGSCC: for.inc33: 978; CGSCC-NEXT: [[INDVARS_IV_NEXT13]] = add nuw nsw i64 [[INDVARS_IV12]], 1 979; CGSCC-NEXT: br label [[FOR_COND25]], !llvm.loop [[LOOP27:![0-9]+]] 980; CGSCC: for.end35: 981; CGSCC-NEXT: ret void 982; 983entry: 984 br label %for.cond 985 986for.cond: ; preds = %for.inc, %entry 987 %indvars.iv = phi i64 [ %indvars.iv.next, %for.inc ], [ 0, %entry ] 988 %exitcond = icmp ne i64 %indvars.iv, 100 989 br i1 %exitcond, label %for.body, label %for.cond.cleanup 990 991for.cond.cleanup: ; preds = %for.cond 992 br label %for.end 993 994for.body: ; preds = %for.cond 995 %i = mul nuw nsw i64 %indvars.iv, 10 996 %arrayidx = getelementptr inbounds [1024 x i8], ptr @GBytes, i64 0, i64 %i 997 store i8 0, ptr %arrayidx, align 2, !tbaa !15 998 br label %for.inc 999 1000for.inc: ; preds = %for.body 1001 %indvars.iv.next = add nuw nsw i64 %indvars.iv, 1 1002 br label %for.cond, !llvm.loop !24 1003 1004for.end: ; preds = %for.cond.cleanup 1005 br label %for.cond2 1006 1007for.cond2: ; preds = %for.inc9, %for.end 1008 %indvars.iv2 = phi i64 [ %indvars.iv.next3, %for.inc9 ], [ 0, %for.end ] 1009 %exitcond6 = icmp ne i64 %indvars.iv2, 10 1010 br i1 %exitcond6, label %for.body5, label %for.cond.cleanup4 1011 1012for.cond.cleanup4: ; preds = %for.cond2 1013 br label %for.end11 1014 1015for.body5: ; preds = %for.cond2 1016 %i15 = mul nuw nsw i64 %indvars.iv2, 10 1017 %i16 = or i64 %i15, 1 1018 %arrayidx8 = getelementptr inbounds float, ptr @GBytes, i64 %i16 1019 store float 0.000000e+00, ptr %arrayidx8, align 4, !tbaa !18 1020 br label %for.inc9 1021 1022for.inc9: ; preds = %for.body5 1023 %indvars.iv.next3 = add nuw nsw i64 %indvars.iv2, 1 1024 br label %for.cond2, !llvm.loop !25 1025 1026for.end11: ; preds = %for.cond.cleanup4 1027 br label %for.cond13 1028 1029for.cond13: ; preds = %for.inc21, %for.end11 1030 %indvars.iv7 = phi i64 [ %indvars.iv.next8, %for.inc21 ], [ 0, %for.end11 ] 1031 %exitcond11 = icmp ne i64 %indvars.iv7, 20 1032 br i1 %exitcond11, label %for.body16, label %for.cond.cleanup15 1033 1034for.cond.cleanup15: ; preds = %for.cond13 1035 br label %for.end23 1036 1037for.body16: ; preds = %for.cond13 1038 %i17 = mul nuw nsw i64 %indvars.iv7, 10 1039 %i18 = add nuw nsw i64 %i17, 2 1040 %arrayidx20 = getelementptr inbounds i64, ptr @GBytes, i64 %i18 1041 store i64 0, ptr %arrayidx20, align 16, !tbaa !20 1042 br label %for.inc21 1043 1044for.inc21: ; preds = %for.body16 1045 %indvars.iv.next8 = add nuw nsw i64 %indvars.iv7, 1 1046 br label %for.cond13, !llvm.loop !26 1047 1048for.end23: ; preds = %for.cond.cleanup15 1049 store i8 0, ptr getelementptr inbounds ([1024 x i8], ptr @GBytes, i64 0, i64 1023), align 1, !tbaa !15 1050 call void @write_arg(ptr getelementptr inbounds ([1024 x i8], ptr @GBytes, i64 0, i64 500), i32 0) 1051 br label %for.cond25 1052 1053for.cond25: ; preds = %for.inc33, %for.end23 1054 %indvars.iv12 = phi i64 [ %indvars.iv.next13, %for.inc33 ], [ 0, %for.end23 ] 1055 %exitcond14 = icmp ne i64 %indvars.iv12, 1024 1056 br i1 %exitcond14, label %for.body28, label %for.cond.cleanup27 1057 1058for.cond.cleanup27: ; preds = %for.cond25 1059 br label %for.end35 1060 1061for.body28: ; preds = %for.cond25 1062 %arrayidx30 = getelementptr inbounds [1024 x i8], ptr @GBytes, i64 0, i64 %indvars.iv12 1063 %i19 = load i8, ptr %arrayidx30, align 1, !tbaa !15 1064 %arrayidx32 = getelementptr inbounds [1024 x i8], ptr @globalBytes, i64 0, i64 %indvars.iv12 1065 store i8 %i19, ptr %arrayidx32, align 1, !tbaa !15 1066 br label %for.inc33 1067 1068for.inc33: ; preds = %for.body28 1069 %indvars.iv.next13 = add nuw nsw i64 %indvars.iv12, 1 1070 br label %for.cond25, !llvm.loop !27 1071 1072for.end35: ; preds = %for.cond.cleanup27 1073 ret void 1074} 1075 1076; static int Flag3; 1077; int static_global_simplifiable_3() { 1078; Flag3 = 1; 1079; return Flag3; 1080; } 1081define i32 @static_global_simplifiable_3() { 1082; TUNIT: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(write) 1083; TUNIT-LABEL: define {{[^@]+}}@static_global_simplifiable_3 1084; TUNIT-SAME: () #[[ATTR5]] { 1085; TUNIT-NEXT: store i32 1, ptr @Flag3, align 4, !tbaa [[TBAA3]] 1086; TUNIT-NEXT: ret i32 1 1087; 1088; CGSCC: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(write) 1089; CGSCC-LABEL: define {{[^@]+}}@static_global_simplifiable_3 1090; CGSCC-SAME: () #[[ATTR6]] { 1091; CGSCC-NEXT: store i32 1, ptr @Flag3, align 4, !tbaa [[TBAA3]] 1092; CGSCC-NEXT: ret i32 1 1093; 1094 store i32 1, ptr @Flag3, align 4, !tbaa !3 1095 %i = load i32, ptr @Flag3, align 4, !tbaa !3 1096 ret i32 %i 1097} 1098 1099; struct S noalias_arg_simplifiable_1(struct S s) { 1100; s.f1 = 1.1; 1101; s.f2 = 2.2; 1102; s.f3 = 3.3; 1103; write_arg(&s.i1, 1); 1104; write_arg(&s.i2, 2); 1105; write_arg(&s.i3, 3); 1106; struct S r; 1107; r.f1 = s.f1; 1108; r.f2 = s.f2 * 2; 1109; r.f3 = s.f3 + s.f1; 1110; r.i1 = s.i1; 1111; r.i2 = s.i2 * 2; 1112; r.i3 = s.i3 + s.i1; 1113; return r; 1114; } 1115; 1116define void @noalias_arg_simplifiable_1(ptr noalias sret(%struct.S) align 4 %agg.result, ptr byval(%struct.S) align 8 %s) { 1117; TUNIT: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(argmem: readwrite) 1118; TUNIT-LABEL: define {{[^@]+}}@noalias_arg_simplifiable_1 1119; TUNIT-SAME: (ptr noalias nofree writeonly sret([[STRUCT_S:%.*]]) align 4 captures(none) dereferenceable_or_null(24) [[AGG_RESULT:%.*]], ptr noalias nofree nonnull byval([[STRUCT_S]]) align 8 captures(none) dereferenceable(24) [[S:%.*]]) #[[ATTR1]] { 1120; TUNIT-NEXT: entry: 1121; TUNIT-NEXT: [[F1:%.*]] = getelementptr inbounds [[STRUCT_S]], ptr [[S]], i64 0, i32 3 1122; TUNIT-NEXT: store float 0x3FF19999A0000000, ptr [[F1]], align 4, !tbaa [[TBAA7]] 1123; TUNIT-NEXT: [[F2:%.*]] = getelementptr inbounds [[STRUCT_S]], ptr [[S]], i64 0, i32 4 1124; TUNIT-NEXT: store float 0x40019999A0000000, ptr [[F2]], align 8, !tbaa [[TBAA10]] 1125; TUNIT-NEXT: [[F3:%.*]] = getelementptr inbounds [[STRUCT_S]], ptr [[S]], i64 0, i32 5 1126; TUNIT-NEXT: store float 0x400A666660000000, ptr [[F3]], align 4, !tbaa [[TBAA11]] 1127; TUNIT-NEXT: call void @write_arg(ptr noalias nofree noundef nonnull writeonly align 8 captures(none) dereferenceable(24) [[S]], i32 noundef 1) #[[ATTR18]] 1128; TUNIT-NEXT: [[I2:%.*]] = getelementptr inbounds [[STRUCT_S]], ptr [[S]], i64 0, i32 1 1129; TUNIT-NEXT: call void @write_arg(ptr nofree noundef nonnull writeonly align 4 captures(none) dereferenceable(20) [[I2]], i32 noundef 2) #[[ATTR18]] 1130; TUNIT-NEXT: [[I3:%.*]] = getelementptr inbounds [[STRUCT_S]], ptr [[S]], i64 0, i32 2 1131; TUNIT-NEXT: call void @write_arg(ptr nofree noundef nonnull writeonly align 8 captures(none) dereferenceable(16) [[I3]], i32 noundef 3) #[[ATTR18]] 1132; TUNIT-NEXT: [[F11:%.*]] = getelementptr inbounds [[STRUCT_S]], ptr [[S]], i64 0, i32 3 1133; TUNIT-NEXT: [[I:%.*]] = load float, ptr [[F11]], align 4, !tbaa [[TBAA7]] 1134; TUNIT-NEXT: [[F12:%.*]] = getelementptr inbounds [[STRUCT_S]], ptr [[AGG_RESULT]], i64 0, i32 3 1135; TUNIT-NEXT: store float [[I]], ptr [[F12]], align 4, !tbaa [[TBAA7]] 1136; TUNIT-NEXT: [[F23:%.*]] = getelementptr inbounds [[STRUCT_S]], ptr [[S]], i64 0, i32 4 1137; TUNIT-NEXT: [[I4:%.*]] = load float, ptr [[F23]], align 8, !tbaa [[TBAA10]] 1138; TUNIT-NEXT: [[MUL:%.*]] = fmul float [[I4]], 2.000000e+00 1139; TUNIT-NEXT: [[F24:%.*]] = getelementptr inbounds [[STRUCT_S]], ptr [[AGG_RESULT]], i64 0, i32 4 1140; TUNIT-NEXT: store float [[MUL]], ptr [[F24]], align 4, !tbaa [[TBAA10]] 1141; TUNIT-NEXT: [[F35:%.*]] = getelementptr inbounds [[STRUCT_S]], ptr [[S]], i64 0, i32 5 1142; TUNIT-NEXT: [[I5:%.*]] = load float, ptr [[F35]], align 4, !tbaa [[TBAA11]] 1143; TUNIT-NEXT: [[F16:%.*]] = getelementptr inbounds [[STRUCT_S]], ptr [[S]], i64 0, i32 3 1144; TUNIT-NEXT: [[I6:%.*]] = load float, ptr [[F16]], align 4, !tbaa [[TBAA7]] 1145; TUNIT-NEXT: [[ADD:%.*]] = fadd float [[I5]], [[I6]] 1146; TUNIT-NEXT: [[F37:%.*]] = getelementptr inbounds [[STRUCT_S]], ptr [[AGG_RESULT]], i64 0, i32 5 1147; TUNIT-NEXT: store float [[ADD]], ptr [[F37]], align 4, !tbaa [[TBAA11]] 1148; TUNIT-NEXT: [[I7:%.*]] = load i32, ptr [[S]], align 8, !tbaa [[TBAA12]] 1149; TUNIT-NEXT: store i32 [[I7]], ptr [[AGG_RESULT]], align 4, !tbaa [[TBAA12]] 1150; TUNIT-NEXT: [[I210:%.*]] = getelementptr inbounds [[STRUCT_S]], ptr [[S]], i64 0, i32 1 1151; TUNIT-NEXT: [[I8:%.*]] = load i32, ptr [[I210]], align 4, !tbaa [[TBAA13]] 1152; TUNIT-NEXT: [[MUL11:%.*]] = shl nsw i32 [[I8]], 1 1153; TUNIT-NEXT: [[I212:%.*]] = getelementptr inbounds [[STRUCT_S]], ptr [[AGG_RESULT]], i64 0, i32 1 1154; TUNIT-NEXT: store i32 [[MUL11]], ptr [[I212]], align 4, !tbaa [[TBAA13]] 1155; TUNIT-NEXT: [[I313:%.*]] = getelementptr inbounds [[STRUCT_S]], ptr [[S]], i64 0, i32 2 1156; TUNIT-NEXT: [[I9:%.*]] = load i32, ptr [[I313]], align 8, !tbaa [[TBAA14]] 1157; TUNIT-NEXT: [[I10:%.*]] = load i32, ptr [[S]], align 8, !tbaa [[TBAA12]] 1158; TUNIT-NEXT: [[ADD15:%.*]] = add nsw i32 [[I9]], [[I10]] 1159; TUNIT-NEXT: [[I316:%.*]] = getelementptr inbounds [[STRUCT_S]], ptr [[AGG_RESULT]], i64 0, i32 2 1160; TUNIT-NEXT: store i32 [[ADD15]], ptr [[I316]], align 4, !tbaa [[TBAA14]] 1161; TUNIT-NEXT: ret void 1162; 1163; CGSCC: Function Attrs: mustprogress nofree nosync nounwind willreturn memory(argmem: readwrite) 1164; CGSCC-LABEL: define {{[^@]+}}@noalias_arg_simplifiable_1 1165; CGSCC-SAME: (ptr noalias nofree noundef nonnull writeonly sret([[STRUCT_S:%.*]]) align 4 captures(none) dereferenceable(24) [[AGG_RESULT:%.*]], ptr noalias nofree noundef nonnull byval([[STRUCT_S]]) align 8 captures(none) dereferenceable(24) [[S:%.*]]) #[[ATTR1]] { 1166; CGSCC-NEXT: entry: 1167; CGSCC-NEXT: [[F1:%.*]] = getelementptr inbounds [[STRUCT_S]], ptr [[S]], i64 0, i32 3 1168; CGSCC-NEXT: store float 0x3FF19999A0000000, ptr [[F1]], align 4, !tbaa [[TBAA7]] 1169; CGSCC-NEXT: [[F2:%.*]] = getelementptr inbounds [[STRUCT_S]], ptr [[S]], i64 0, i32 4 1170; CGSCC-NEXT: store float 0x40019999A0000000, ptr [[F2]], align 8, !tbaa [[TBAA10]] 1171; CGSCC-NEXT: [[F3:%.*]] = getelementptr inbounds [[STRUCT_S]], ptr [[S]], i64 0, i32 5 1172; CGSCC-NEXT: store float 0x400A666660000000, ptr [[F3]], align 4, !tbaa [[TBAA11]] 1173; CGSCC-NEXT: call void @write_arg(ptr noalias nofree noundef nonnull writeonly align 8 captures(none) dereferenceable(24) [[S]], i32 noundef 1) #[[ATTR21]] 1174; CGSCC-NEXT: [[I2:%.*]] = getelementptr inbounds [[STRUCT_S]], ptr [[S]], i64 0, i32 1 1175; CGSCC-NEXT: call void @write_arg(ptr nofree noundef nonnull writeonly align 4 captures(none) dereferenceable(20) [[I2]], i32 noundef 2) #[[ATTR21]] 1176; CGSCC-NEXT: [[I3:%.*]] = getelementptr inbounds [[STRUCT_S]], ptr [[S]], i64 0, i32 2 1177; CGSCC-NEXT: call void @write_arg(ptr nofree noundef nonnull writeonly align 8 captures(none) dereferenceable(16) [[I3]], i32 noundef 3) #[[ATTR21]] 1178; CGSCC-NEXT: [[F11:%.*]] = getelementptr inbounds [[STRUCT_S]], ptr [[S]], i64 0, i32 3 1179; CGSCC-NEXT: [[I:%.*]] = load float, ptr [[F11]], align 4, !tbaa [[TBAA7]] 1180; CGSCC-NEXT: [[F12:%.*]] = getelementptr inbounds [[STRUCT_S]], ptr [[AGG_RESULT]], i64 0, i32 3 1181; CGSCC-NEXT: store float [[I]], ptr [[F12]], align 4, !tbaa [[TBAA7]] 1182; CGSCC-NEXT: [[F23:%.*]] = getelementptr inbounds [[STRUCT_S]], ptr [[S]], i64 0, i32 4 1183; CGSCC-NEXT: [[I4:%.*]] = load float, ptr [[F23]], align 8, !tbaa [[TBAA10]] 1184; CGSCC-NEXT: [[MUL:%.*]] = fmul float [[I4]], 2.000000e+00 1185; CGSCC-NEXT: [[F24:%.*]] = getelementptr inbounds [[STRUCT_S]], ptr [[AGG_RESULT]], i64 0, i32 4 1186; CGSCC-NEXT: store float [[MUL]], ptr [[F24]], align 4, !tbaa [[TBAA10]] 1187; CGSCC-NEXT: [[F35:%.*]] = getelementptr inbounds [[STRUCT_S]], ptr [[S]], i64 0, i32 5 1188; CGSCC-NEXT: [[I5:%.*]] = load float, ptr [[F35]], align 4, !tbaa [[TBAA11]] 1189; CGSCC-NEXT: [[F16:%.*]] = getelementptr inbounds [[STRUCT_S]], ptr [[S]], i64 0, i32 3 1190; CGSCC-NEXT: [[I6:%.*]] = load float, ptr [[F16]], align 4, !tbaa [[TBAA7]] 1191; CGSCC-NEXT: [[ADD:%.*]] = fadd float [[I5]], [[I6]] 1192; CGSCC-NEXT: [[F37:%.*]] = getelementptr inbounds [[STRUCT_S]], ptr [[AGG_RESULT]], i64 0, i32 5 1193; CGSCC-NEXT: store float [[ADD]], ptr [[F37]], align 4, !tbaa [[TBAA11]] 1194; CGSCC-NEXT: [[I7:%.*]] = load i32, ptr [[S]], align 8, !tbaa [[TBAA12]] 1195; CGSCC-NEXT: store i32 [[I7]], ptr [[AGG_RESULT]], align 4, !tbaa [[TBAA12]] 1196; CGSCC-NEXT: [[I210:%.*]] = getelementptr inbounds [[STRUCT_S]], ptr [[S]], i64 0, i32 1 1197; CGSCC-NEXT: [[I8:%.*]] = load i32, ptr [[I210]], align 4, !tbaa [[TBAA13]] 1198; CGSCC-NEXT: [[MUL11:%.*]] = shl nsw i32 [[I8]], 1 1199; CGSCC-NEXT: [[I212:%.*]] = getelementptr inbounds [[STRUCT_S]], ptr [[AGG_RESULT]], i64 0, i32 1 1200; CGSCC-NEXT: store i32 [[MUL11]], ptr [[I212]], align 4, !tbaa [[TBAA13]] 1201; CGSCC-NEXT: [[I313:%.*]] = getelementptr inbounds [[STRUCT_S]], ptr [[S]], i64 0, i32 2 1202; CGSCC-NEXT: [[I9:%.*]] = load i32, ptr [[I313]], align 8, !tbaa [[TBAA14]] 1203; CGSCC-NEXT: [[I10:%.*]] = load i32, ptr [[S]], align 8, !tbaa [[TBAA12]] 1204; CGSCC-NEXT: [[ADD15:%.*]] = add nsw i32 [[I9]], [[I10]] 1205; CGSCC-NEXT: [[I316:%.*]] = getelementptr inbounds [[STRUCT_S]], ptr [[AGG_RESULT]], i64 0, i32 2 1206; CGSCC-NEXT: store i32 [[ADD15]], ptr [[I316]], align 4, !tbaa [[TBAA14]] 1207; CGSCC-NEXT: ret void 1208; 1209entry: 1210 %f1 = getelementptr inbounds %struct.S, ptr %s, i64 0, i32 3 1211 store float 0x3FF19999A0000000, ptr %f1, align 4, !tbaa !7 1212 %f2 = getelementptr inbounds %struct.S, ptr %s, i64 0, i32 4 1213 store float 0x40019999A0000000, ptr %f2, align 8, !tbaa !10 1214 %f3 = getelementptr inbounds %struct.S, ptr %s, i64 0, i32 5 1215 store float 0x400A666660000000, ptr %f3, align 4, !tbaa !11 1216 call void @write_arg(ptr nonnull %s, i32 1) 1217 %i2 = getelementptr inbounds %struct.S, ptr %s, i64 0, i32 1 1218 call void @write_arg(ptr nonnull %i2, i32 2) 1219 %i3 = getelementptr inbounds %struct.S, ptr %s, i64 0, i32 2 1220 call void @write_arg(ptr nonnull %i3, i32 3) 1221 %f11 = getelementptr inbounds %struct.S, ptr %s, i64 0, i32 3 1222 %i = load float, ptr %f11, align 4, !tbaa !7 1223 %f12 = getelementptr inbounds %struct.S, ptr %agg.result, i64 0, i32 3 1224 store float %i, ptr %f12, align 4, !tbaa !7 1225 %f23 = getelementptr inbounds %struct.S, ptr %s, i64 0, i32 4 1226 %i4 = load float, ptr %f23, align 8, !tbaa !10 1227 %mul = fmul float %i4, 2.000000e+00 1228 %f24 = getelementptr inbounds %struct.S, ptr %agg.result, i64 0, i32 4 1229 store float %mul, ptr %f24, align 4, !tbaa !10 1230 %f35 = getelementptr inbounds %struct.S, ptr %s, i64 0, i32 5 1231 %i5 = load float, ptr %f35, align 4, !tbaa !11 1232 %f16 = getelementptr inbounds %struct.S, ptr %s, i64 0, i32 3 1233 %i6 = load float, ptr %f16, align 4, !tbaa !7 1234 %add = fadd float %i5, %i6 1235 %f37 = getelementptr inbounds %struct.S, ptr %agg.result, i64 0, i32 5 1236 store float %add, ptr %f37, align 4, !tbaa !11 1237 %i7 = load i32, ptr %s, align 8, !tbaa !12 1238 store i32 %i7, ptr %agg.result, align 4, !tbaa !12 1239 %i210 = getelementptr inbounds %struct.S, ptr %s, i64 0, i32 1 1240 %i8 = load i32, ptr %i210, align 4, !tbaa !13 1241 %mul11 = shl nsw i32 %i8, 1 1242 %i212 = getelementptr inbounds %struct.S, ptr %agg.result, i64 0, i32 1 1243 store i32 %mul11, ptr %i212, align 4, !tbaa !13 1244 %i313 = getelementptr inbounds %struct.S, ptr %s, i64 0, i32 2 1245 %i9 = load i32, ptr %i313, align 8, !tbaa !14 1246 %i10 = load i32, ptr %s, align 8, !tbaa !12 1247 %add15 = add nsw i32 %i9, %i10 1248 %i316 = getelementptr inbounds %struct.S, ptr %agg.result, i64 0, i32 2 1249 store i32 %add15, ptr %i316, align 4, !tbaa !14 1250 ret void 1251} 1252 1253; void noalias_arg_simplifiable_2(char Bytes[1024]) { 1254; for (int i = 0; i < 100; ++i) 1255; Bytes[i * 10] = 0; 1256; for (int i = 0; i < 10; ++i) 1257; ((float *)Bytes)[i * 10 + 1] = 0; 1258; for (int i = 0; i < 20; ++i) 1259; ((long long int *)Bytes)[i * 10 + 2] = 0; 1260; Bytes[1023] = 0; 1261; write_arg((int *)&Bytes[500], 0); 1262; struct S R; 1263; for (int i = 0; i < 1024; ++i) 1264; globalBytes[i] = Bytes[i]; 1265; } 1266; 1267define void @noalias_arg_simplifiable_2(ptr %Bytes) { 1268; TUNIT: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn 1269; TUNIT-LABEL: define {{[^@]+}}@noalias_arg_simplifiable_2 1270; TUNIT-SAME: (ptr nofree captures(none) [[BYTES:%.*]]) #[[ATTR3]] { 1271; TUNIT-NEXT: entry: 1272; TUNIT-NEXT: br label [[FOR_COND:%.*]] 1273; TUNIT: for.cond: 1274; TUNIT-NEXT: [[INDVARS_IV:%.*]] = phi i64 [ [[INDVARS_IV_NEXT:%.*]], [[FOR_INC:%.*]] ], [ 0, [[ENTRY:%.*]] ] 1275; TUNIT-NEXT: [[EXITCOND:%.*]] = icmp ne i64 [[INDVARS_IV]], 100 1276; TUNIT-NEXT: br i1 [[EXITCOND]], label [[FOR_BODY:%.*]], label [[FOR_COND_CLEANUP:%.*]] 1277; TUNIT: for.cond.cleanup: 1278; TUNIT-NEXT: br label [[FOR_END:%.*]] 1279; TUNIT: for.body: 1280; TUNIT-NEXT: [[I:%.*]] = mul nuw nsw i64 [[INDVARS_IV]], 10 1281; TUNIT-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds i8, ptr [[BYTES]], i64 [[I]] 1282; TUNIT-NEXT: store i8 0, ptr [[ARRAYIDX]], align 1, !tbaa [[TBAA19]] 1283; TUNIT-NEXT: br label [[FOR_INC]] 1284; TUNIT: for.inc: 1285; TUNIT-NEXT: [[INDVARS_IV_NEXT]] = add nuw nsw i64 [[INDVARS_IV]], 1 1286; TUNIT-NEXT: br label [[FOR_COND]], !llvm.loop [[LOOP25:![0-9]+]] 1287; TUNIT: for.end: 1288; TUNIT-NEXT: br label [[FOR_COND2:%.*]] 1289; TUNIT: for.cond2: 1290; TUNIT-NEXT: [[INDVARS_IV2:%.*]] = phi i64 [ [[INDVARS_IV_NEXT3:%.*]], [[FOR_INC9:%.*]] ], [ 0, [[FOR_END]] ] 1291; TUNIT-NEXT: [[EXITCOND6:%.*]] = icmp ne i64 [[INDVARS_IV2]], 10 1292; TUNIT-NEXT: br i1 [[EXITCOND6]], label [[FOR_BODY5:%.*]], label [[FOR_COND_CLEANUP4:%.*]] 1293; TUNIT: for.cond.cleanup4: 1294; TUNIT-NEXT: br label [[FOR_END11:%.*]] 1295; TUNIT: for.body5: 1296; TUNIT-NEXT: [[I16:%.*]] = mul nuw nsw i64 [[INDVARS_IV2]], 10 1297; TUNIT-NEXT: [[I17:%.*]] = or i64 [[I16]], 1 1298; TUNIT-NEXT: [[ARRAYIDX8:%.*]] = getelementptr inbounds float, ptr [[BYTES]], i64 [[I17]] 1299; TUNIT-NEXT: store float 0.000000e+00, ptr [[ARRAYIDX8]], align 4, !tbaa [[TBAA26:![0-9]+]] 1300; TUNIT-NEXT: br label [[FOR_INC9]] 1301; TUNIT: for.inc9: 1302; TUNIT-NEXT: [[INDVARS_IV_NEXT3]] = add nuw nsw i64 [[INDVARS_IV2]], 1 1303; TUNIT-NEXT: br label [[FOR_COND2]], !llvm.loop [[LOOP27:![0-9]+]] 1304; TUNIT: for.end11: 1305; TUNIT-NEXT: br label [[FOR_COND13:%.*]] 1306; TUNIT: for.cond13: 1307; TUNIT-NEXT: [[INDVARS_IV7:%.*]] = phi i64 [ [[INDVARS_IV_NEXT8:%.*]], [[FOR_INC21:%.*]] ], [ 0, [[FOR_END11]] ] 1308; TUNIT-NEXT: [[EXITCOND11:%.*]] = icmp ne i64 [[INDVARS_IV7]], 20 1309; TUNIT-NEXT: br i1 [[EXITCOND11]], label [[FOR_BODY16:%.*]], label [[FOR_COND_CLEANUP15:%.*]] 1310; TUNIT: for.cond.cleanup15: 1311; TUNIT-NEXT: br label [[FOR_END23:%.*]] 1312; TUNIT: for.body16: 1313; TUNIT-NEXT: [[I19:%.*]] = mul nuw nsw i64 [[INDVARS_IV7]], 10 1314; TUNIT-NEXT: [[I20:%.*]] = add nuw nsw i64 [[I19]], 2 1315; TUNIT-NEXT: [[ARRAYIDX20:%.*]] = getelementptr inbounds i64, ptr [[BYTES]], i64 [[I20]] 1316; TUNIT-NEXT: store i64 0, ptr [[ARRAYIDX20]], align 8, !tbaa [[TBAA28:![0-9]+]] 1317; TUNIT-NEXT: br label [[FOR_INC21]] 1318; TUNIT: for.inc21: 1319; TUNIT-NEXT: [[INDVARS_IV_NEXT8]] = add nuw nsw i64 [[INDVARS_IV7]], 1 1320; TUNIT-NEXT: br label [[FOR_COND13]], !llvm.loop [[LOOP30:![0-9]+]] 1321; TUNIT: for.end23: 1322; TUNIT-NEXT: [[ARRAYIDX24:%.*]] = getelementptr inbounds i8, ptr [[BYTES]], i64 1023 1323; TUNIT-NEXT: store i8 0, ptr [[ARRAYIDX24]], align 1, !tbaa [[TBAA19]] 1324; TUNIT-NEXT: [[ARRAYIDX25:%.*]] = getelementptr inbounds i8, ptr [[BYTES]], i64 500 1325; TUNIT-NEXT: call void @write_arg(ptr nofree noundef nonnull writeonly align 4 captures(none) [[ARRAYIDX25]], i32 noundef 0) #[[ATTR18]] 1326; TUNIT-NEXT: br label [[FOR_COND27:%.*]] 1327; TUNIT: for.cond27: 1328; TUNIT-NEXT: [[INDVARS_IV12:%.*]] = phi i64 [ [[INDVARS_IV_NEXT13:%.*]], [[FOR_INC35:%.*]] ], [ 0, [[FOR_END23]] ] 1329; TUNIT-NEXT: [[EXITCOND14:%.*]] = icmp ne i64 [[INDVARS_IV12]], 1024 1330; TUNIT-NEXT: br i1 [[EXITCOND14]], label [[FOR_BODY30:%.*]], label [[FOR_COND_CLEANUP29:%.*]] 1331; TUNIT: for.cond.cleanup29: 1332; TUNIT-NEXT: br label [[FOR_END37:%.*]] 1333; TUNIT: for.body30: 1334; TUNIT-NEXT: [[ARRAYIDX32:%.*]] = getelementptr inbounds i8, ptr [[BYTES]], i64 [[INDVARS_IV12]] 1335; TUNIT-NEXT: [[I22:%.*]] = load i8, ptr [[ARRAYIDX32]], align 1, !tbaa [[TBAA19]] 1336; TUNIT-NEXT: [[ARRAYIDX34:%.*]] = getelementptr inbounds [1024 x i8], ptr @globalBytes, i64 0, i64 [[INDVARS_IV12]] 1337; TUNIT-NEXT: store i8 [[I22]], ptr [[ARRAYIDX34]], align 1, !tbaa [[TBAA19]] 1338; TUNIT-NEXT: br label [[FOR_INC35]] 1339; TUNIT: for.inc35: 1340; TUNIT-NEXT: [[INDVARS_IV_NEXT13]] = add nuw nsw i64 [[INDVARS_IV12]], 1 1341; TUNIT-NEXT: br label [[FOR_COND27]], !llvm.loop [[LOOP31:![0-9]+]] 1342; TUNIT: for.end37: 1343; TUNIT-NEXT: ret void 1344; 1345; CGSCC: Function Attrs: mustprogress nofree nosync nounwind willreturn 1346; CGSCC-LABEL: define {{[^@]+}}@noalias_arg_simplifiable_2 1347; CGSCC-SAME: (ptr nofree captures(none) [[BYTES:%.*]]) #[[ATTR3]] { 1348; CGSCC-NEXT: entry: 1349; CGSCC-NEXT: br label [[FOR_COND:%.*]] 1350; CGSCC: for.cond: 1351; CGSCC-NEXT: [[INDVARS_IV:%.*]] = phi i64 [ [[INDVARS_IV_NEXT:%.*]], [[FOR_INC:%.*]] ], [ 0, [[ENTRY:%.*]] ] 1352; CGSCC-NEXT: [[EXITCOND:%.*]] = icmp ne i64 [[INDVARS_IV]], 100 1353; CGSCC-NEXT: br i1 [[EXITCOND]], label [[FOR_BODY:%.*]], label [[FOR_COND_CLEANUP:%.*]] 1354; CGSCC: for.cond.cleanup: 1355; CGSCC-NEXT: br label [[FOR_END:%.*]] 1356; CGSCC: for.body: 1357; CGSCC-NEXT: [[I:%.*]] = mul nuw nsw i64 [[INDVARS_IV]], 10 1358; CGSCC-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds i8, ptr [[BYTES]], i64 [[I]] 1359; CGSCC-NEXT: store i8 0, ptr [[ARRAYIDX]], align 1, !tbaa [[TBAA15]] 1360; CGSCC-NEXT: br label [[FOR_INC]] 1361; CGSCC: for.inc: 1362; CGSCC-NEXT: [[INDVARS_IV_NEXT]] = add nuw nsw i64 [[INDVARS_IV]], 1 1363; CGSCC-NEXT: br label [[FOR_COND]], !llvm.loop [[LOOP28:![0-9]+]] 1364; CGSCC: for.end: 1365; CGSCC-NEXT: br label [[FOR_COND2:%.*]] 1366; CGSCC: for.cond2: 1367; CGSCC-NEXT: [[INDVARS_IV2:%.*]] = phi i64 [ [[INDVARS_IV_NEXT3:%.*]], [[FOR_INC9:%.*]] ], [ 0, [[FOR_END]] ] 1368; CGSCC-NEXT: [[EXITCOND6:%.*]] = icmp ne i64 [[INDVARS_IV2]], 10 1369; CGSCC-NEXT: br i1 [[EXITCOND6]], label [[FOR_BODY5:%.*]], label [[FOR_COND_CLEANUP4:%.*]] 1370; CGSCC: for.cond.cleanup4: 1371; CGSCC-NEXT: br label [[FOR_END11:%.*]] 1372; CGSCC: for.body5: 1373; CGSCC-NEXT: [[I16:%.*]] = mul nuw nsw i64 [[INDVARS_IV2]], 10 1374; CGSCC-NEXT: [[I17:%.*]] = or i64 [[I16]], 1 1375; CGSCC-NEXT: [[ARRAYIDX8:%.*]] = getelementptr inbounds float, ptr [[BYTES]], i64 [[I17]] 1376; CGSCC-NEXT: store float 0.000000e+00, ptr [[ARRAYIDX8]], align 4, !tbaa [[TBAA18]] 1377; CGSCC-NEXT: br label [[FOR_INC9]] 1378; CGSCC: for.inc9: 1379; CGSCC-NEXT: [[INDVARS_IV_NEXT3]] = add nuw nsw i64 [[INDVARS_IV2]], 1 1380; CGSCC-NEXT: br label [[FOR_COND2]], !llvm.loop [[LOOP29:![0-9]+]] 1381; CGSCC: for.end11: 1382; CGSCC-NEXT: br label [[FOR_COND13:%.*]] 1383; CGSCC: for.cond13: 1384; CGSCC-NEXT: [[INDVARS_IV7:%.*]] = phi i64 [ [[INDVARS_IV_NEXT8:%.*]], [[FOR_INC21:%.*]] ], [ 0, [[FOR_END11]] ] 1385; CGSCC-NEXT: [[EXITCOND11:%.*]] = icmp ne i64 [[INDVARS_IV7]], 20 1386; CGSCC-NEXT: br i1 [[EXITCOND11]], label [[FOR_BODY16:%.*]], label [[FOR_COND_CLEANUP15:%.*]] 1387; CGSCC: for.cond.cleanup15: 1388; CGSCC-NEXT: br label [[FOR_END23:%.*]] 1389; CGSCC: for.body16: 1390; CGSCC-NEXT: [[I19:%.*]] = mul nuw nsw i64 [[INDVARS_IV7]], 10 1391; CGSCC-NEXT: [[I20:%.*]] = add nuw nsw i64 [[I19]], 2 1392; CGSCC-NEXT: [[ARRAYIDX20:%.*]] = getelementptr inbounds i64, ptr [[BYTES]], i64 [[I20]] 1393; CGSCC-NEXT: store i64 0, ptr [[ARRAYIDX20]], align 8, !tbaa [[TBAA20]] 1394; CGSCC-NEXT: br label [[FOR_INC21]] 1395; CGSCC: for.inc21: 1396; CGSCC-NEXT: [[INDVARS_IV_NEXT8]] = add nuw nsw i64 [[INDVARS_IV7]], 1 1397; CGSCC-NEXT: br label [[FOR_COND13]], !llvm.loop [[LOOP30:![0-9]+]] 1398; CGSCC: for.end23: 1399; CGSCC-NEXT: [[ARRAYIDX24:%.*]] = getelementptr inbounds i8, ptr [[BYTES]], i64 1023 1400; CGSCC-NEXT: store i8 0, ptr [[ARRAYIDX24]], align 1, !tbaa [[TBAA15]] 1401; CGSCC-NEXT: [[ARRAYIDX25:%.*]] = getelementptr inbounds i8, ptr [[BYTES]], i64 500 1402; CGSCC-NEXT: call void @write_arg(ptr nofree noundef nonnull writeonly align 4 captures(none) dereferenceable(4) [[ARRAYIDX25]], i32 noundef 0) #[[ATTR21]] 1403; CGSCC-NEXT: br label [[FOR_COND27:%.*]] 1404; CGSCC: for.cond27: 1405; CGSCC-NEXT: [[INDVARS_IV12:%.*]] = phi i64 [ [[INDVARS_IV_NEXT13:%.*]], [[FOR_INC35:%.*]] ], [ 0, [[FOR_END23]] ] 1406; CGSCC-NEXT: [[EXITCOND14:%.*]] = icmp ne i64 [[INDVARS_IV12]], 1024 1407; CGSCC-NEXT: br i1 [[EXITCOND14]], label [[FOR_BODY30:%.*]], label [[FOR_COND_CLEANUP29:%.*]] 1408; CGSCC: for.cond.cleanup29: 1409; CGSCC-NEXT: br label [[FOR_END37:%.*]] 1410; CGSCC: for.body30: 1411; CGSCC-NEXT: [[ARRAYIDX32:%.*]] = getelementptr inbounds i8, ptr [[BYTES]], i64 [[INDVARS_IV12]] 1412; CGSCC-NEXT: [[I22:%.*]] = load i8, ptr [[ARRAYIDX32]], align 1, !tbaa [[TBAA15]] 1413; CGSCC-NEXT: [[ARRAYIDX34:%.*]] = getelementptr inbounds [1024 x i8], ptr @globalBytes, i64 0, i64 [[INDVARS_IV12]] 1414; CGSCC-NEXT: store i8 [[I22]], ptr [[ARRAYIDX34]], align 1, !tbaa [[TBAA15]] 1415; CGSCC-NEXT: br label [[FOR_INC35]] 1416; CGSCC: for.inc35: 1417; CGSCC-NEXT: [[INDVARS_IV_NEXT13]] = add nuw nsw i64 [[INDVARS_IV12]], 1 1418; CGSCC-NEXT: br label [[FOR_COND27]], !llvm.loop [[LOOP31:![0-9]+]] 1419; CGSCC: for.end37: 1420; CGSCC-NEXT: ret void 1421; 1422entry: 1423 br label %for.cond 1424 1425for.cond: ; preds = %for.inc, %entry 1426 %indvars.iv = phi i64 [ %indvars.iv.next, %for.inc ], [ 0, %entry ] 1427 %exitcond = icmp ne i64 %indvars.iv, 100 1428 br i1 %exitcond, label %for.body, label %for.cond.cleanup 1429 1430for.cond.cleanup: ; preds = %for.cond 1431 br label %for.end 1432 1433for.body: ; preds = %for.cond 1434 %i = mul nuw nsw i64 %indvars.iv, 10 1435 %arrayidx = getelementptr inbounds i8, ptr %Bytes, i64 %i 1436 store i8 0, ptr %arrayidx, align 1, !tbaa !15 1437 br label %for.inc 1438 1439for.inc: ; preds = %for.body 1440 %indvars.iv.next = add nuw nsw i64 %indvars.iv, 1 1441 br label %for.cond, !llvm.loop !28 1442 1443for.end: ; preds = %for.cond.cleanup 1444 br label %for.cond2 1445 1446for.cond2: ; preds = %for.inc9, %for.end 1447 %indvars.iv2 = phi i64 [ %indvars.iv.next3, %for.inc9 ], [ 0, %for.end ] 1448 %exitcond6 = icmp ne i64 %indvars.iv2, 10 1449 br i1 %exitcond6, label %for.body5, label %for.cond.cleanup4 1450 1451for.cond.cleanup4: ; preds = %for.cond2 1452 br label %for.end11 1453 1454for.body5: ; preds = %for.cond2 1455 %i16 = mul nuw nsw i64 %indvars.iv2, 10 1456 %i17 = or i64 %i16, 1 1457 %arrayidx8 = getelementptr inbounds float, ptr %Bytes, i64 %i17 1458 store float 0.000000e+00, ptr %arrayidx8, align 4, !tbaa !18 1459 br label %for.inc9 1460 1461for.inc9: ; preds = %for.body5 1462 %indvars.iv.next3 = add nuw nsw i64 %indvars.iv2, 1 1463 br label %for.cond2, !llvm.loop !29 1464 1465for.end11: ; preds = %for.cond.cleanup4 1466 br label %for.cond13 1467 1468for.cond13: ; preds = %for.inc21, %for.end11 1469 %indvars.iv7 = phi i64 [ %indvars.iv.next8, %for.inc21 ], [ 0, %for.end11 ] 1470 %exitcond11 = icmp ne i64 %indvars.iv7, 20 1471 br i1 %exitcond11, label %for.body16, label %for.cond.cleanup15 1472 1473for.cond.cleanup15: ; preds = %for.cond13 1474 br label %for.end23 1475 1476for.body16: ; preds = %for.cond13 1477 %i19 = mul nuw nsw i64 %indvars.iv7, 10 1478 %i20 = add nuw nsw i64 %i19, 2 1479 %arrayidx20 = getelementptr inbounds i64, ptr %Bytes, i64 %i20 1480 store i64 0, ptr %arrayidx20, align 8, !tbaa !20 1481 br label %for.inc21 1482 1483for.inc21: ; preds = %for.body16 1484 %indvars.iv.next8 = add nuw nsw i64 %indvars.iv7, 1 1485 br label %for.cond13, !llvm.loop !30 1486 1487for.end23: ; preds = %for.cond.cleanup15 1488 %arrayidx24 = getelementptr inbounds i8, ptr %Bytes, i64 1023 1489 store i8 0, ptr %arrayidx24, align 1, !tbaa !15 1490 %arrayidx25 = getelementptr inbounds i8, ptr %Bytes, i64 500 1491 call void @write_arg(ptr nonnull %arrayidx25, i32 0) 1492 br label %for.cond27 1493 1494for.cond27: ; preds = %for.inc35, %for.end23 1495 %indvars.iv12 = phi i64 [ %indvars.iv.next13, %for.inc35 ], [ 0, %for.end23 ] 1496 %exitcond14 = icmp ne i64 %indvars.iv12, 1024 1497 br i1 %exitcond14, label %for.body30, label %for.cond.cleanup29 1498 1499for.cond.cleanup29: ; preds = %for.cond27 1500 br label %for.end37 1501 1502for.body30: ; preds = %for.cond27 1503 %arrayidx32 = getelementptr inbounds i8, ptr %Bytes, i64 %indvars.iv12 1504 %i22 = load i8, ptr %arrayidx32, align 1, !tbaa !15 1505 %arrayidx34 = getelementptr inbounds [1024 x i8], ptr @globalBytes, i64 0, i64 %indvars.iv12 1506 store i8 %i22, ptr %arrayidx34, align 1, !tbaa !15 1507 br label %for.inc35 1508 1509for.inc35: ; preds = %for.body30 1510 %indvars.iv.next13 = add nuw nsw i64 %indvars.iv12, 1 1511 br label %for.cond27, !llvm.loop !31 1512 1513for.end37: ; preds = %for.cond.cleanup29 1514 ret void 1515} 1516 1517; int local_alloca_not_simplifiable_1() { 1518; int X, Y, Z; 1519; X = Y = 1; 1520; escape(&X); 1521; write_random(&Y); 1522; Z = X ? 1 : 2; 1523; return X + Y + Z; 1524; } 1525; 1526define i32 @local_alloca_not_simplifiable_1() { 1527; TUNIT-LABEL: define {{[^@]+}}@local_alloca_not_simplifiable_1() { 1528; TUNIT-NEXT: entry: 1529; TUNIT-NEXT: [[X:%.*]] = alloca i32, align 4 1530; TUNIT-NEXT: [[Y:%.*]] = alloca i32, align 4 1531; TUNIT-NEXT: call void @llvm.lifetime.start.p0(i64 noundef 4, ptr nofree noundef nonnull align 4 captures(none) dereferenceable(4) [[X]]) #[[ATTR17]] 1532; TUNIT-NEXT: call void @llvm.lifetime.start.p0(i64 noundef 4, ptr noalias nofree noundef nonnull align 4 captures(none) dereferenceable(4) [[Y]]) #[[ATTR17]] 1533; TUNIT-NEXT: store i32 1, ptr [[Y]], align 4, !tbaa [[TBAA3]] 1534; TUNIT-NEXT: store i32 1, ptr [[X]], align 4, !tbaa [[TBAA3]] 1535; TUNIT-NEXT: call void @escape(ptr noundef nonnull align 4 dereferenceable(4) [[X]]) 1536; TUNIT-NEXT: call void @write_random(ptr noalias nofree noundef nonnull writeonly align 4 captures(none) dereferenceable(4) [[Y]]) 1537; TUNIT-NEXT: [[I3:%.*]] = load i32, ptr [[X]], align 4, !tbaa [[TBAA3]] 1538; TUNIT-NEXT: [[TOBOOL_NOT:%.*]] = icmp eq i32 [[I3]], 0 1539; TUNIT-NEXT: [[COND:%.*]] = select i1 [[TOBOOL_NOT]], i32 2, i32 1 1540; TUNIT-NEXT: [[I4:%.*]] = load i32, ptr [[Y]], align 4, !tbaa [[TBAA3]] 1541; TUNIT-NEXT: [[ADD:%.*]] = add nsw i32 [[I3]], [[I4]] 1542; TUNIT-NEXT: [[ADD1:%.*]] = add nsw i32 [[ADD]], [[COND]] 1543; TUNIT-NEXT: call void @llvm.lifetime.end.p0(i64 noundef 4, ptr noalias nofree noundef nonnull align 4 captures(none) dereferenceable(4) [[Y]]) 1544; TUNIT-NEXT: call void @llvm.lifetime.end.p0(i64 noundef 4, ptr nofree noundef nonnull align 4 captures(none) dereferenceable(4) [[X]]) 1545; TUNIT-NEXT: ret i32 [[ADD1]] 1546; 1547; CGSCC-LABEL: define {{[^@]+}}@local_alloca_not_simplifiable_1() { 1548; CGSCC-NEXT: entry: 1549; CGSCC-NEXT: [[X:%.*]] = alloca i32, align 4 1550; CGSCC-NEXT: [[Y:%.*]] = alloca i32, align 4 1551; CGSCC-NEXT: call void @llvm.lifetime.start.p0(i64 noundef 4, ptr nofree noundef nonnull align 4 captures(none) dereferenceable(4) [[X]]) #[[ATTR20]] 1552; CGSCC-NEXT: call void @llvm.lifetime.start.p0(i64 noundef 4, ptr noalias nofree noundef nonnull align 4 captures(none) dereferenceable(4) [[Y]]) #[[ATTR20]] 1553; CGSCC-NEXT: store i32 1, ptr [[Y]], align 4, !tbaa [[TBAA3]] 1554; CGSCC-NEXT: store i32 1, ptr [[X]], align 4, !tbaa [[TBAA3]] 1555; CGSCC-NEXT: call void @escape(ptr noundef nonnull align 4 dereferenceable(4) [[X]]) 1556; CGSCC-NEXT: call void @write_random(ptr noalias nofree noundef nonnull writeonly align 4 captures(none) dereferenceable(4) [[Y]]) 1557; CGSCC-NEXT: [[I3:%.*]] = load i32, ptr [[X]], align 4, !tbaa [[TBAA3]] 1558; CGSCC-NEXT: [[TOBOOL_NOT:%.*]] = icmp eq i32 [[I3]], 0 1559; CGSCC-NEXT: [[COND:%.*]] = select i1 [[TOBOOL_NOT]], i32 2, i32 1 1560; CGSCC-NEXT: [[I4:%.*]] = load i32, ptr [[Y]], align 4, !tbaa [[TBAA3]] 1561; CGSCC-NEXT: [[ADD:%.*]] = add nsw i32 [[I3]], [[I4]] 1562; CGSCC-NEXT: [[ADD1:%.*]] = add nsw i32 [[ADD]], [[COND]] 1563; CGSCC-NEXT: call void @llvm.lifetime.end.p0(i64 noundef 4, ptr noalias nofree noundef nonnull align 4 captures(none) dereferenceable(4) [[Y]]) 1564; CGSCC-NEXT: call void @llvm.lifetime.end.p0(i64 noundef 4, ptr nofree noundef nonnull align 4 captures(none) dereferenceable(4) [[X]]) 1565; CGSCC-NEXT: ret i32 [[ADD1]] 1566; 1567entry: 1568 %X = alloca i32, align 4 1569 %Y = alloca i32, align 4 1570 call void @llvm.lifetime.start.p0(i64 4, ptr nonnull %X) 1571 call void @llvm.lifetime.start.p0(i64 4, ptr nonnull %Y) 1572 store i32 1, ptr %Y, align 4, !tbaa !3 1573 store i32 1, ptr %X, align 4, !tbaa !3 1574 call void @escape(ptr nonnull %X) 1575 call void @write_random(ptr nonnull %Y) 1576 %i3 = load i32, ptr %X, align 4, !tbaa !3 1577 %tobool.not = icmp eq i32 %i3, 0 1578 %cond = select i1 %tobool.not, i32 2, i32 1 1579 %i4 = load i32, ptr %Y, align 4, !tbaa !3 1580 %add = add nsw i32 %i3, %i4 1581 %add1 = add nsw i32 %add, %cond 1582 call void @llvm.lifetime.end.p0(i64 4, ptr nonnull %Y) 1583 call void @llvm.lifetime.end.p0(i64 4, ptr nonnull %X) 1584 ret i32 %add1 1585} 1586 1587define i8 @local_alloca_not_simplifiable_2(i64 %index1, i64 %index2, i1 %cnd) { 1588; CHECK: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none) 1589; CHECK-LABEL: define {{[^@]+}}@local_alloca_not_simplifiable_2 1590; CHECK-SAME: (i64 [[INDEX1:%.*]], i64 [[INDEX2:%.*]], i1 noundef [[CND:%.*]]) #[[ATTR4]] { 1591; CHECK-NEXT: entry: 1592; CHECK-NEXT: [[BYTES:%.*]] = alloca [1024 x i8], align 16 1593; CHECK-NEXT: store i8 7, ptr [[BYTES]], align 16 1594; CHECK-NEXT: br i1 [[CND]], label [[LEFT:%.*]], label [[RIGHT:%.*]] 1595; CHECK: left: 1596; CHECK-NEXT: [[GEP1:%.*]] = getelementptr inbounds [1024 x i8], ptr [[BYTES]], i64 0, i64 [[INDEX1]] 1597; CHECK-NEXT: br label [[JOIN:%.*]] 1598; CHECK: right: 1599; CHECK-NEXT: [[GEP2:%.*]] = getelementptr inbounds [1024 x i8], ptr [[BYTES]], i64 0, i64 [[INDEX2]] 1600; CHECK-NEXT: br label [[JOIN]] 1601; CHECK: join: 1602; CHECK-NEXT: [[GEP_JOIN:%.*]] = phi ptr [ [[GEP1]], [[LEFT]] ], [ [[GEP2]], [[RIGHT]] ] 1603; CHECK-NEXT: store i8 9, ptr [[GEP_JOIN]], align 4 1604; CHECK-NEXT: [[I:%.*]] = load i8, ptr [[BYTES]], align 16 1605; CHECK-NEXT: ret i8 [[I]] 1606; 1607entry: 1608 %Bytes = alloca [1024 x i8], align 16 1609 store i8 7, ptr %Bytes, align 4 1610 br i1 %cnd, label %left, label %right 1611 1612left: ; preds = %entry 1613 %gep1 = getelementptr inbounds [1024 x i8], ptr %Bytes, i64 0, i64 %index1 1614 br label %join 1615 1616right: ; preds = %entry 1617 %gep2 = getelementptr inbounds [1024 x i8], ptr %Bytes, i64 0, i64 %index2 1618 br label %join 1619 1620join: ; preds = %right, %left 1621 %gep.join = phi ptr [ %gep1, %left ], [ %gep2, %right ] 1622 store i8 9, ptr %gep.join, align 4 1623 1624 ; This load cannot be replaced by the value 7 from %entry, since the previous 1625 ; store interferes due to its unknown offset. 1626 %i = load i8, ptr %Bytes, align 4 1627 ret i8 %i 1628} 1629 1630; We could simplify these if we separate accessed bins wrt. alignment (here mod 4). 1631define i32 @unknown_access_mixed_simplifiable(i32 %arg1, i32 %arg2) { 1632; CHECK: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none) 1633; CHECK-LABEL: define {{[^@]+}}@unknown_access_mixed_simplifiable 1634; CHECK-SAME: (i32 [[ARG1:%.*]], i32 [[ARG2:%.*]]) #[[ATTR4]] { 1635; CHECK-NEXT: entry: 1636; CHECK-NEXT: [[S:%.*]] = alloca [[STRUCT_S:%.*]], align 4 1637; CHECK-NEXT: [[GEP1:%.*]] = getelementptr inbounds [[STRUCT_S]], ptr [[S]], i64 0, i32 2 1638; CHECK-NEXT: [[GEP2:%.*]] = getelementptr inbounds i32, ptr [[S]], i32 [[ARG1]] 1639; CHECK-NEXT: [[GEP3:%.*]] = getelementptr inbounds i32, ptr [[S]], i32 [[ARG2]] 1640; CHECK-NEXT: store i32 7, ptr [[GEP1]], align 4 1641; CHECK-NEXT: store i32 7, ptr [[GEP2]], align 4 1642; CHECK-NEXT: store i32 7, ptr [[GEP3]], align 4 1643; CHECK-NEXT: [[L1:%.*]] = load i32, ptr [[GEP1]], align 4 1644; CHECK-NEXT: [[L2:%.*]] = load i32, ptr [[GEP2]], align 4 1645; CHECK-NEXT: [[L3:%.*]] = load i32, ptr [[GEP3]], align 4 1646; CHECK-NEXT: [[ADD1:%.*]] = add i32 [[L1]], [[L2]] 1647; CHECK-NEXT: [[ADD2:%.*]] = add i32 [[ADD1]], [[L3]] 1648; CHECK-NEXT: ret i32 [[ADD2]] 1649; 1650entry: 1651 %s = alloca %struct.S, align 4 1652 %gep1 = getelementptr inbounds %struct.S, ptr %s, i64 0, i32 2 1653 %gep2 = getelementptr inbounds i32, ptr %s, i32 %arg1 1654 %gep3 = getelementptr inbounds i32, ptr %s, i32 %arg2 1655 store i32 7, ptr %gep1 1656 store i32 7, ptr %gep2 1657 store i32 7, ptr %gep3 1658 %l1 = load i32, ptr %gep1 1659 %l2 = load i32, ptr %gep2 1660 %l3 = load i32, ptr %gep3 1661 %add1 = add i32 %l1, %l2 1662 %add2 = add i32 %add1, %l3 1663 ret i32 %add2 1664} 1665 1666; The access to bc4b could go anywhere, nothing is simplifiable. 1667define i32 @unknown_access_mixed_not_simplifiable(i32 %arg1, i32 %arg2, i32 %arg3) { 1668; CHECK: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none) 1669; CHECK-LABEL: define {{[^@]+}}@unknown_access_mixed_not_simplifiable 1670; CHECK-SAME: (i32 [[ARG1:%.*]], i32 [[ARG2:%.*]], i32 [[ARG3:%.*]]) #[[ATTR4]] { 1671; CHECK-NEXT: entry: 1672; CHECK-NEXT: [[S:%.*]] = alloca [[STRUCT_S:%.*]], align 4 1673; CHECK-NEXT: [[GEP1:%.*]] = getelementptr inbounds [[STRUCT_S]], ptr [[S]], i64 0, i32 2 1674; CHECK-NEXT: [[GEP2:%.*]] = getelementptr inbounds i32, ptr [[S]], i32 [[ARG1]] 1675; CHECK-NEXT: [[GEP3:%.*]] = getelementptr inbounds i32, ptr [[S]], i32 [[ARG2]] 1676; CHECK-NEXT: [[GEP4:%.*]] = getelementptr inbounds i8, ptr [[S]], i32 [[ARG3]] 1677; CHECK-NEXT: store i32 7, ptr [[GEP1]], align 4 1678; CHECK-NEXT: store i32 7, ptr [[GEP2]], align 4 1679; CHECK-NEXT: store i32 7, ptr [[GEP3]], align 4 1680; CHECK-NEXT: store i32 7, ptr [[GEP4]], align 4 1681; CHECK-NEXT: [[L1:%.*]] = load i32, ptr [[GEP1]], align 4 1682; CHECK-NEXT: [[L2:%.*]] = load i32, ptr [[GEP2]], align 4 1683; CHECK-NEXT: [[L3:%.*]] = load i32, ptr [[GEP3]], align 4 1684; CHECK-NEXT: [[L4:%.*]] = load i32, ptr [[GEP4]], align 4 1685; CHECK-NEXT: [[ADD1:%.*]] = add i32 [[L1]], [[L2]] 1686; CHECK-NEXT: [[ADD2:%.*]] = add i32 [[ADD1]], [[L3]] 1687; CHECK-NEXT: [[ADD3:%.*]] = add i32 [[ADD2]], [[L4]] 1688; CHECK-NEXT: ret i32 [[ADD3]] 1689; 1690entry: 1691 %s = alloca %struct.S, align 4 1692 %gep1 = getelementptr inbounds %struct.S, ptr %s, i64 0, i32 2 1693 %gep2 = getelementptr inbounds i32, ptr %s, i32 %arg1 1694 %gep3 = getelementptr inbounds i32, ptr %s, i32 %arg2 1695 %gep4 = getelementptr inbounds i8, ptr %s, i32 %arg3 1696 store i32 7, ptr %gep1 1697 store i32 7, ptr %gep2 1698 store i32 7, ptr %gep3 1699 store i32 7, ptr %gep4 1700 %l1 = load i32, ptr %gep1 1701 %l2 = load i32, ptr %gep2 1702 %l3 = load i32, ptr %gep3 1703 %l4 = load i32, ptr %gep4 1704 %add1 = add i32 %l1, %l2 1705 %add2 = add i32 %add1, %l3 1706 %add3 = add i32 %add2, %l4 1707 ret i32 %add3 1708} 1709 1710declare void @escape(ptr) 1711 1712; int Flag0 = 0; 1713; int global_not_simplifiable_1(int cnd) { 1714; return Flag0; 1715; } 1716; 1717define i32 @global_not_simplifiable_1(i32 %cnd) { 1718; TUNIT: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(read) 1719; TUNIT-LABEL: define {{[^@]+}}@global_not_simplifiable_1 1720; TUNIT-SAME: (i32 [[CND:%.*]]) #[[ATTR6:[0-9]+]] { 1721; TUNIT-NEXT: entry: 1722; TUNIT-NEXT: [[I:%.*]] = load i32, ptr @Flag0, align 4, !tbaa [[TBAA3]] 1723; TUNIT-NEXT: ret i32 [[I]] 1724; 1725; CGSCC: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(read) 1726; CGSCC-LABEL: define {{[^@]+}}@global_not_simplifiable_1 1727; CGSCC-SAME: (i32 [[CND:%.*]]) #[[ATTR7:[0-9]+]] { 1728; CGSCC-NEXT: entry: 1729; CGSCC-NEXT: [[I:%.*]] = load i32, ptr @Flag0, align 4, !tbaa [[TBAA3]] 1730; CGSCC-NEXT: ret i32 [[I]] 1731; 1732entry: 1733 %i = load i32, ptr @Flag0, align 4, !tbaa !3 1734 ret i32 %i 1735} 1736 1737; static int Flag1 __attribute__((loader_uninitialized)); 1738; int static_global_not_simplifiable_1(int cnd) { 1739; int v = Flag1; 1740; sync(); 1741; if (cnd) 1742; Flag1 = 1; 1743; return v; 1744; } 1745; 1746define i32 @static_global_not_simplifiable_1(i32 %cnd) { 1747; CHECK-LABEL: define {{[^@]+}}@static_global_not_simplifiable_1 1748; CHECK-SAME: (i32 [[CND:%.*]]) { 1749; CHECK-NEXT: entry: 1750; CHECK-NEXT: call void @sync() 1751; CHECK-NEXT: [[TOBOOL_NOT:%.*]] = icmp eq i32 [[CND]], 0 1752; CHECK-NEXT: br i1 [[TOBOOL_NOT]], label [[IF_END:%.*]], label [[IF_THEN:%.*]] 1753; CHECK: if.then: 1754; CHECK-NEXT: br label [[IF_END]] 1755; CHECK: if.end: 1756; CHECK-NEXT: ret i32 1 1757; 1758entry: 1759 %i = load i32, ptr @Flag1, align 4, !tbaa !3 1760 call void @sync() 1761 %tobool.not = icmp eq i32 %cnd, 0 1762 br i1 %tobool.not, label %if.end, label %if.then 1763 1764if.then: ; preds = %entry 1765 store i32 1, ptr @Flag1, align 4, !tbaa !3 1766 br label %if.end 1767 1768if.end: ; preds = %if.then, %entry 1769 ret i32 %i 1770} 1771 1772declare void @sync() 1773 1774; static int Flag2 __attribute__((loader_uninitialized)); 1775; int static_global_simplifiable_4(int cnd) { 1776; Flag2 = 1; 1777; sync(); 1778; int v = Flag2; 1779; Flag2 = 2; 1780; return v; 1781; } 1782define i32 @static_global_simplifiable_4(i32 %cnd) { 1783; CHECK-LABEL: define {{[^@]+}}@static_global_simplifiable_4 1784; CHECK-SAME: (i32 [[CND:%.*]]) { 1785; CHECK-NEXT: entry: 1786; CHECK-NEXT: store i32 1, ptr @Flag2, align 4, !tbaa [[TBAA3]] 1787; CHECK-NEXT: call void @sync() 1788; CHECK-NEXT: [[I:%.*]] = load i32, ptr @Flag2, align 4, !tbaa [[TBAA3]] 1789; CHECK-NEXT: store i32 2, ptr @Flag2, align 4, !tbaa [[TBAA3]] 1790; CHECK-NEXT: ret i32 [[I]] 1791; 1792entry: 1793 store i32 1, ptr @Flag2, align 4, !tbaa !3 1794 call void @sync() 1795 %i = load i32, ptr @Flag2, align 4, !tbaa !3 1796 store i32 2, ptr @Flag2, align 4, !tbaa !3 1797 ret i32 %i 1798} 1799 1800; static int Flag2 __attribute__((loader_uninitialized)); 1801; int static_global_not_simplifiable_2(int cnd) { 1802; Flag2 = 1; 1803; sync(); 1804; int v = Flag2; 1805; Flag2 = 2; 1806; return v; 1807; } 1808define i32 @static_global_not_simplifiable_2(i32 %cnd) { 1809; TUNIT-LABEL: define {{[^@]+}}@static_global_not_simplifiable_2 1810; TUNIT-SAME: (i32 [[CND:%.*]]) { 1811; TUNIT-NEXT: entry: 1812; TUNIT-NEXT: store i32 1, ptr @Flag4, align 4, !tbaa [[TBAA3]] 1813; TUNIT-NEXT: call void @sync() #[[ATTR19:[0-9]+]] 1814; TUNIT-NEXT: [[I:%.*]] = load i32, ptr @Flag4, align 4, !tbaa [[TBAA3]] 1815; TUNIT-NEXT: store i32 2, ptr @Flag4, align 4, !tbaa [[TBAA3]] 1816; TUNIT-NEXT: ret i32 [[I]] 1817; 1818; CGSCC-LABEL: define {{[^@]+}}@static_global_not_simplifiable_2 1819; CGSCC-SAME: (i32 [[CND:%.*]]) { 1820; CGSCC-NEXT: entry: 1821; CGSCC-NEXT: store i32 1, ptr @Flag4, align 4, !tbaa [[TBAA3]] 1822; CGSCC-NEXT: call void @sync() #[[ATTR22:[0-9]+]] 1823; CGSCC-NEXT: [[I:%.*]] = load i32, ptr @Flag4, align 4, !tbaa [[TBAA3]] 1824; CGSCC-NEXT: store i32 2, ptr @Flag4, align 4, !tbaa [[TBAA3]] 1825; CGSCC-NEXT: ret i32 [[I]] 1826; 1827entry: 1828 store i32 1, ptr @Flag4, align 4, !tbaa !3 1829 call void @sync() nocallback 1830 %i = load i32, ptr @Flag4, align 4, !tbaa !3 1831 store i32 2, ptr @Flag4, align 4, !tbaa !3 1832 ret i32 %i 1833} 1834define void @static_global_not_simplifiable_2_helper() { 1835; TUNIT: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(write) 1836; TUNIT-LABEL: define {{[^@]+}}@static_global_not_simplifiable_2_helper 1837; TUNIT-SAME: () #[[ATTR5]] { 1838; TUNIT-NEXT: store i32 2, ptr @Flag4, align 4, !tbaa [[TBAA3]] 1839; TUNIT-NEXT: ret void 1840; 1841; CGSCC: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(write) 1842; CGSCC-LABEL: define {{[^@]+}}@static_global_not_simplifiable_2_helper 1843; CGSCC-SAME: () #[[ATTR6]] { 1844; CGSCC-NEXT: store i32 2, ptr @Flag4, align 4, !tbaa [[TBAA3]] 1845; CGSCC-NEXT: ret void 1846; 1847 store i32 2, ptr @Flag4, align 4, !tbaa !3 1848 ret void 1849} 1850 1851; Similiar to static_global_simplifiable_3 but with a may-store. 1852define i32 @static_global_not_simplifiable_3(i1 %c, ptr %p) { 1853; TUNIT: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn 1854; TUNIT-LABEL: define {{[^@]+}}@static_global_not_simplifiable_3 1855; TUNIT-SAME: (i1 [[C:%.*]], ptr nofree writeonly captures(none) [[P:%.*]]) #[[ATTR3]] { 1856; TUNIT-NEXT: [[SEL:%.*]] = select i1 [[C]], ptr @Flag3, ptr [[P]] 1857; TUNIT-NEXT: store i32 1, ptr [[SEL]], align 4, !tbaa [[TBAA3]] 1858; TUNIT-NEXT: [[I:%.*]] = load i32, ptr @Flag3, align 4, !tbaa [[TBAA3]] 1859; TUNIT-NEXT: ret i32 [[I]] 1860; 1861; CGSCC: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn 1862; CGSCC-LABEL: define {{[^@]+}}@static_global_not_simplifiable_3 1863; CGSCC-SAME: (i1 [[C:%.*]], ptr nofree writeonly captures(none) [[P:%.*]]) #[[ATTR5]] { 1864; CGSCC-NEXT: [[SEL:%.*]] = select i1 [[C]], ptr @Flag3, ptr [[P]] 1865; CGSCC-NEXT: store i32 1, ptr [[SEL]], align 4, !tbaa [[TBAA3]] 1866; CGSCC-NEXT: [[I:%.*]] = load i32, ptr @Flag3, align 4, !tbaa [[TBAA3]] 1867; CGSCC-NEXT: ret i32 [[I]] 1868; 1869 %sel = select i1 %c, ptr @Flag3, ptr %p 1870 store i32 1, ptr %sel, align 4, !tbaa !3 1871 %i = load i32, ptr @Flag3, align 4, !tbaa !3 1872 ret i32 %i 1873} 1874 1875 1876; int write_read{,_static,_static_undef}_global(void) { 1877; Gint{,static,_static_undef}1 = 7; 1878; return Gint1; 1879; } 1880; void write{,_static,_static_undef}_global(void) { 1881; Gint{,static,_static_undef}2 = 7; 1882; } 1883; int read{,_static,_static_undef}_global(void) { 1884; return Gint{,static,_static_undef}2; 1885; } 1886; 1887; FIXME: We could replace these loads. 1888define i32 @write_read_global() { 1889; TUNIT: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn 1890; TUNIT-LABEL: define {{[^@]+}}@write_read_global 1891; TUNIT-SAME: () #[[ATTR3]] { 1892; TUNIT-NEXT: store i32 7, ptr @Gint1, align 4 1893; TUNIT-NEXT: [[L:%.*]] = load i32, ptr @Gint1, align 4 1894; TUNIT-NEXT: ret i32 [[L]] 1895; 1896; CGSCC: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn 1897; CGSCC-LABEL: define {{[^@]+}}@write_read_global 1898; CGSCC-SAME: () #[[ATTR5]] { 1899; CGSCC-NEXT: store i32 7, ptr @Gint1, align 4 1900; CGSCC-NEXT: [[L:%.*]] = load i32, ptr @Gint1, align 4 1901; CGSCC-NEXT: ret i32 [[L]] 1902; 1903 store i32 7, ptr @Gint1 1904 %l = load i32, ptr @Gint1 1905 ret i32 %l 1906} 1907define void @write_global() { 1908; TUNIT: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(write) 1909; TUNIT-LABEL: define {{[^@]+}}@write_global 1910; TUNIT-SAME: () #[[ATTR5]] { 1911; TUNIT-NEXT: store i32 7, ptr @Gint2, align 4 1912; TUNIT-NEXT: ret void 1913; 1914; CGSCC: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(write) 1915; CGSCC-LABEL: define {{[^@]+}}@write_global 1916; CGSCC-SAME: () #[[ATTR6]] { 1917; CGSCC-NEXT: store i32 7, ptr @Gint2, align 4 1918; CGSCC-NEXT: ret void 1919; 1920 store i32 7, ptr @Gint2 1921 ret void 1922} 1923define i32 @read_global() { 1924; TUNIT: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(read) 1925; TUNIT-LABEL: define {{[^@]+}}@read_global 1926; TUNIT-SAME: () #[[ATTR6]] { 1927; TUNIT-NEXT: [[L:%.*]] = load i32, ptr @Gint2, align 4 1928; TUNIT-NEXT: ret i32 [[L]] 1929; 1930; CGSCC: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(read) 1931; CGSCC-LABEL: define {{[^@]+}}@read_global 1932; CGSCC-SAME: () #[[ATTR7]] { 1933; CGSCC-NEXT: [[L:%.*]] = load i32, ptr @Gint2, align 4 1934; CGSCC-NEXT: ret i32 [[L]] 1935; 1936 %l = load i32, ptr @Gint2 1937 ret i32 %l 1938} 1939define i32 @write_read_static_global() { 1940; TUNIT: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(write) 1941; TUNIT-LABEL: define {{[^@]+}}@write_read_static_global 1942; TUNIT-SAME: () #[[ATTR5]] { 1943; TUNIT-NEXT: ret i32 7 1944; 1945; CGSCC: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(write) 1946; CGSCC-LABEL: define {{[^@]+}}@write_read_static_global 1947; CGSCC-SAME: () #[[ATTR6]] { 1948; CGSCC-NEXT: ret i32 7 1949; 1950 store i32 7, ptr @Gstatic_int1 1951 %l = load i32, ptr @Gstatic_int1 1952 ret i32 %l 1953} 1954define void @write_static_global() { 1955; TUNIT: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(write) 1956; TUNIT-LABEL: define {{[^@]+}}@write_static_global 1957; TUNIT-SAME: () #[[ATTR5]] { 1958; TUNIT-NEXT: store i32 7, ptr @Gstatic_int2, align 4 1959; TUNIT-NEXT: ret void 1960; 1961; CGSCC: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(write) 1962; CGSCC-LABEL: define {{[^@]+}}@write_static_global 1963; CGSCC-SAME: () #[[ATTR6]] { 1964; CGSCC-NEXT: store i32 7, ptr @Gstatic_int2, align 4 1965; CGSCC-NEXT: ret void 1966; 1967 store i32 7, ptr @Gstatic_int2 1968 ret void 1969} 1970define i32 @read_static_global() { 1971; TUNIT: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(read) 1972; TUNIT-LABEL: define {{[^@]+}}@read_static_global 1973; TUNIT-SAME: () #[[ATTR6]] { 1974; TUNIT-NEXT: [[L:%.*]] = load i32, ptr @Gstatic_int2, align 4 1975; TUNIT-NEXT: ret i32 [[L]] 1976; 1977; CGSCC: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(read) 1978; CGSCC-LABEL: define {{[^@]+}}@read_static_global 1979; CGSCC-SAME: () #[[ATTR7]] { 1980; CGSCC-NEXT: [[L:%.*]] = load i32, ptr @Gstatic_int2, align 4 1981; CGSCC-NEXT: ret i32 [[L]] 1982; 1983 %l = load i32, ptr @Gstatic_int2 1984 ret i32 %l 1985} 1986define i32 @write_read_static_undef_global() { 1987; TUNIT: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(write) 1988; TUNIT-LABEL: define {{[^@]+}}@write_read_static_undef_global 1989; TUNIT-SAME: () #[[ATTR5]] { 1990; TUNIT-NEXT: ret i32 7 1991; 1992; CGSCC: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(write) 1993; CGSCC-LABEL: define {{[^@]+}}@write_read_static_undef_global 1994; CGSCC-SAME: () #[[ATTR6]] { 1995; CGSCC-NEXT: ret i32 7 1996; 1997 store i32 7, ptr @Gstatic_undef_int1 1998 %l = load i32, ptr @Gstatic_undef_int1 1999 ret i32 %l 2000} 2001define void @write_static_undef_global() { 2002; TUNIT: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(write) 2003; TUNIT-LABEL: define {{[^@]+}}@write_static_undef_global 2004; TUNIT-SAME: () #[[ATTR5]] { 2005; TUNIT-NEXT: ret void 2006; 2007; CGSCC: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(write) 2008; CGSCC-LABEL: define {{[^@]+}}@write_static_undef_global 2009; CGSCC-SAME: () #[[ATTR6]] { 2010; CGSCC-NEXT: store i32 7, ptr @Gstatic_undef_int2, align 4 2011; CGSCC-NEXT: ret void 2012; 2013 store i32 7, ptr @Gstatic_undef_int2 2014 ret void 2015} 2016define i32 @read_static_undef_global() { 2017; CHECK: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none) 2018; CHECK-LABEL: define {{[^@]+}}@read_static_undef_global 2019; CHECK-SAME: () #[[ATTR4]] { 2020; CHECK-NEXT: ret i32 7 2021; 2022 %l = load i32, ptr @Gstatic_undef_int2 2023 ret i32 %l 2024} 2025 2026define i32 @single_read_of_static_global() { 2027; CHECK: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none) 2028; CHECK-LABEL: define {{[^@]+}}@single_read_of_static_global 2029; CHECK-SAME: () #[[ATTR4]] { 2030; CHECK-NEXT: ret i32 0 2031; 2032 %l = load i32, ptr @Gstatic_int3 2033 ret i32 %l 2034} 2035 2036define i8 @phi_store() { 2037; CHECK: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none) 2038; CHECK-LABEL: define {{[^@]+}}@phi_store 2039; CHECK-SAME: () #[[ATTR4]] { 2040; CHECK-NEXT: entry: 2041; CHECK-NEXT: [[A:%.*]] = alloca i16, align 2 2042; CHECK-NEXT: br label [[LOOP:%.*]] 2043; CHECK: loop: 2044; CHECK-NEXT: [[P:%.*]] = phi ptr [ [[A]], [[ENTRY:%.*]] ], [ [[G:%.*]], [[LOOP]] ] 2045; CHECK-NEXT: [[I:%.*]] = phi i8 [ 0, [[ENTRY]] ], [ [[O:%.*]], [[LOOP]] ] 2046; CHECK-NEXT: store i8 1, ptr [[P]], align 1 2047; CHECK-NEXT: [[G]] = getelementptr i8, ptr [[P]], i64 1 2048; CHECK-NEXT: [[O]] = add nsw i8 [[I]], 1 2049; CHECK-NEXT: [[C:%.*]] = icmp eq i8 [[O]], 2 2050; CHECK-NEXT: br i1 [[C]], label [[END:%.*]], label [[LOOP]] 2051; CHECK: end: 2052; CHECK-NEXT: [[S:%.*]] = getelementptr i8, ptr [[A]], i64 1 2053; CHECK-NEXT: [[L:%.*]] = load i8, ptr [[S]], align 1 2054; CHECK-NEXT: ret i8 [[L]] 2055; 2056entry: 2057 %a = alloca i16 2058 br label %loop 2059loop: 2060 %p = phi ptr [%a, %entry], [%g, %loop] 2061 %i = phi i8 [0, %entry], [%o, %loop] 2062 store i8 1, ptr %p 2063 %g = getelementptr i8, ptr %p, i64 1 2064 %o = add nsw i8 %i, 1 2065 %c = icmp eq i8 %o, 2 2066 br i1 %c, label %end, label %loop 2067end: 2068 %s = getelementptr i8, ptr %a, i64 1 2069 %l = load i8, ptr %s 2070 ret i8 %l 2071} 2072 2073; FIXME: This function returns 1. 2074define i8 @phi_no_store_1() { 2075; 2076; TUNIT: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn 2077; TUNIT-LABEL: define {{[^@]+}}@phi_no_store_1 2078; TUNIT-SAME: () #[[ATTR3]] { 2079; TUNIT-NEXT: entry: 2080; TUNIT-NEXT: br label [[LOOP:%.*]] 2081; TUNIT: loop: 2082; TUNIT-NEXT: [[P:%.*]] = phi ptr [ @a1, [[ENTRY:%.*]] ], [ [[G:%.*]], [[LOOP]] ] 2083; TUNIT-NEXT: [[I:%.*]] = phi i8 [ 0, [[ENTRY]] ], [ [[O:%.*]], [[LOOP]] ] 2084; TUNIT-NEXT: store i8 1, ptr [[P]], align 1 2085; TUNIT-NEXT: [[G]] = getelementptr i8, ptr [[P]], i64 1 2086; TUNIT-NEXT: [[O]] = add nsw i8 [[I]], 1 2087; TUNIT-NEXT: [[C:%.*]] = icmp eq i8 [[O]], 3 2088; TUNIT-NEXT: br i1 [[C]], label [[END:%.*]], label [[LOOP]] 2089; TUNIT: end: 2090; TUNIT-NEXT: [[S11:%.*]] = getelementptr i8, ptr @a1, i64 2 2091; TUNIT-NEXT: [[L11:%.*]] = load i8, ptr [[S11]], align 2 2092; TUNIT-NEXT: [[S12:%.*]] = getelementptr i8, ptr @a1, i64 3 2093; TUNIT-NEXT: [[L12:%.*]] = load i8, ptr [[S12]], align 1 2094; TUNIT-NEXT: [[ADD:%.*]] = add i8 [[L11]], [[L12]] 2095; TUNIT-NEXT: ret i8 [[ADD]] 2096; 2097; CGSCC: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn 2098; CGSCC-LABEL: define {{[^@]+}}@phi_no_store_1 2099; CGSCC-SAME: () #[[ATTR5]] { 2100; CGSCC-NEXT: entry: 2101; CGSCC-NEXT: br label [[LOOP:%.*]] 2102; CGSCC: loop: 2103; CGSCC-NEXT: [[P:%.*]] = phi ptr [ @a1, [[ENTRY:%.*]] ], [ [[G:%.*]], [[LOOP]] ] 2104; CGSCC-NEXT: [[I:%.*]] = phi i8 [ 0, [[ENTRY]] ], [ [[O:%.*]], [[LOOP]] ] 2105; CGSCC-NEXT: store i8 1, ptr [[P]], align 1 2106; CGSCC-NEXT: [[G]] = getelementptr i8, ptr [[P]], i64 1 2107; CGSCC-NEXT: [[O]] = add nsw i8 [[I]], 1 2108; CGSCC-NEXT: [[C:%.*]] = icmp eq i8 [[O]], 3 2109; CGSCC-NEXT: br i1 [[C]], label [[END:%.*]], label [[LOOP]] 2110; CGSCC: end: 2111; CGSCC-NEXT: [[S11:%.*]] = getelementptr i8, ptr @a1, i64 2 2112; CGSCC-NEXT: [[L11:%.*]] = load i8, ptr [[S11]], align 2 2113; CGSCC-NEXT: [[S12:%.*]] = getelementptr i8, ptr @a1, i64 3 2114; CGSCC-NEXT: [[L12:%.*]] = load i8, ptr [[S12]], align 1 2115; CGSCC-NEXT: [[ADD:%.*]] = add i8 [[L11]], [[L12]] 2116; CGSCC-NEXT: ret i8 [[ADD]] 2117; 2118entry: 2119 br label %loop 2120loop: 2121 %p = phi ptr [@a1, %entry], [%g, %loop] 2122 %i = phi i8 [0, %entry], [%o, %loop] 2123 store i8 1, ptr %p 2124 %g = getelementptr i8, ptr %p, i64 1 2125 %o = add nsw i8 %i, 1 2126 %c = icmp eq i8 %o, 3 2127 br i1 %c, label %end, label %loop 2128end: 2129 %s11 = getelementptr i8, ptr @a1, i64 2 2130 %l11 = load i8, ptr %s11 2131 %s12 = getelementptr i8, ptr @a1, i64 3 2132 %l12 = load i8, ptr %s12 2133 %add = add i8 %l11, %l12 2134 ret i8 %add 2135} 2136 2137; FIXME: This function returns 1. 2138define i8 @phi_no_store_2() { 2139; 2140; TUNIT: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn 2141; TUNIT-LABEL: define {{[^@]+}}@phi_no_store_2 2142; TUNIT-SAME: () #[[ATTR3]] { 2143; TUNIT-NEXT: entry: 2144; TUNIT-NEXT: br label [[LOOP:%.*]] 2145; TUNIT: loop: 2146; TUNIT-NEXT: [[P:%.*]] = phi ptr [ @a2, [[ENTRY:%.*]] ], [ [[G:%.*]], [[LOOP]] ] 2147; TUNIT-NEXT: [[I:%.*]] = phi i8 [ 0, [[ENTRY]] ], [ [[O:%.*]], [[LOOP]] ] 2148; TUNIT-NEXT: store i8 1, ptr [[P]], align 1 2149; TUNIT-NEXT: [[G]] = getelementptr i8, ptr @a2, i64 2 2150; TUNIT-NEXT: [[O]] = add nsw i8 [[I]], 1 2151; TUNIT-NEXT: [[C:%.*]] = icmp eq i8 [[O]], 7 2152; TUNIT-NEXT: br i1 [[C]], label [[END:%.*]], label [[LOOP]] 2153; TUNIT: end: 2154; TUNIT-NEXT: [[S21:%.*]] = getelementptr i8, ptr @a2, i64 2 2155; TUNIT-NEXT: [[L21:%.*]] = load i8, ptr [[S21]], align 2 2156; TUNIT-NEXT: [[S22:%.*]] = getelementptr i8, ptr @a2, i64 3 2157; TUNIT-NEXT: [[L22:%.*]] = load i8, ptr [[S22]], align 1 2158; TUNIT-NEXT: [[ADD:%.*]] = add i8 [[L21]], [[L22]] 2159; TUNIT-NEXT: ret i8 [[ADD]] 2160; 2161; CGSCC: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn 2162; CGSCC-LABEL: define {{[^@]+}}@phi_no_store_2 2163; CGSCC-SAME: () #[[ATTR5]] { 2164; CGSCC-NEXT: entry: 2165; CGSCC-NEXT: br label [[LOOP:%.*]] 2166; CGSCC: loop: 2167; CGSCC-NEXT: [[P:%.*]] = phi ptr [ @a2, [[ENTRY:%.*]] ], [ [[G:%.*]], [[LOOP]] ] 2168; CGSCC-NEXT: [[I:%.*]] = phi i8 [ 0, [[ENTRY]] ], [ [[O:%.*]], [[LOOP]] ] 2169; CGSCC-NEXT: store i8 1, ptr [[P]], align 1 2170; CGSCC-NEXT: [[G]] = getelementptr i8, ptr @a2, i64 2 2171; CGSCC-NEXT: [[O]] = add nsw i8 [[I]], 1 2172; CGSCC-NEXT: [[C:%.*]] = icmp eq i8 [[O]], 7 2173; CGSCC-NEXT: br i1 [[C]], label [[END:%.*]], label [[LOOP]] 2174; CGSCC: end: 2175; CGSCC-NEXT: [[S21:%.*]] = getelementptr i8, ptr @a2, i64 2 2176; CGSCC-NEXT: [[L21:%.*]] = load i8, ptr [[S21]], align 2 2177; CGSCC-NEXT: [[S22:%.*]] = getelementptr i8, ptr @a2, i64 3 2178; CGSCC-NEXT: [[L22:%.*]] = load i8, ptr [[S22]], align 1 2179; CGSCC-NEXT: [[ADD:%.*]] = add i8 [[L21]], [[L22]] 2180; CGSCC-NEXT: ret i8 [[ADD]] 2181; 2182entry: 2183 br label %loop 2184loop: 2185 %p = phi ptr [@a2, %entry], [%g, %loop] 2186 %i = phi i8 [0, %entry], [%o, %loop] 2187 store i8 1, ptr %p 2188 %g = getelementptr i8, ptr @a2, i64 2 2189 %o = add nsw i8 %i, 1 2190 %c = icmp eq i8 %o, 7 2191 br i1 %c, label %end, label %loop 2192end: 2193 %s21 = getelementptr i8, ptr @a2, i64 2 2194 %l21 = load i8, ptr %s21 2195 %s22 = getelementptr i8, ptr @a2, i64 3 2196 %l22 = load i8, ptr %s22 2197 %add = add i8 %l21, %l22 2198 ret i8 %add 2199} 2200 2201define i8 @phi_no_store_3() { 2202; TUNIT: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn 2203; TUNIT-LABEL: define {{[^@]+}}@phi_no_store_3 2204; TUNIT-SAME: () #[[ATTR3]] { 2205; TUNIT-NEXT: entry: 2206; TUNIT-NEXT: [[S30:%.*]] = getelementptr i8, ptr @a3, i64 3 2207; TUNIT-NEXT: store i8 0, ptr [[S30]], align 1 2208; TUNIT-NEXT: br label [[LOOP:%.*]] 2209; TUNIT: loop: 2210; TUNIT-NEXT: [[P:%.*]] = phi ptr [ @a3, [[ENTRY:%.*]] ], [ [[G:%.*]], [[LOOP]] ] 2211; TUNIT-NEXT: [[I:%.*]] = phi i8 [ 0, [[ENTRY]] ], [ [[O:%.*]], [[LOOP]] ] 2212; TUNIT-NEXT: store i8 1, ptr [[P]], align 1 2213; TUNIT-NEXT: [[G]] = getelementptr i8, ptr @a3, i64 2 2214; TUNIT-NEXT: [[O]] = add nsw i8 [[I]], 1 2215; TUNIT-NEXT: [[C:%.*]] = icmp eq i8 [[O]], 7 2216; TUNIT-NEXT: br i1 [[C]], label [[END:%.*]], label [[LOOP]] 2217; TUNIT: end: 2218; TUNIT-NEXT: [[S31:%.*]] = getelementptr i8, ptr @a3, i64 2 2219; TUNIT-NEXT: [[L31:%.*]] = load i8, ptr [[S31]], align 2 2220; TUNIT-NEXT: [[S32:%.*]] = getelementptr i8, ptr @a3, i64 3 2221; TUNIT-NEXT: [[L32:%.*]] = load i8, ptr [[S32]], align 1 2222; TUNIT-NEXT: [[ADD:%.*]] = add i8 [[L31]], [[L32]] 2223; TUNIT-NEXT: [[S34:%.*]] = getelementptr i8, ptr @a3, i64 4 2224; TUNIT-NEXT: [[L34:%.*]] = load i8, ptr [[S34]], align 4 2225; TUNIT-NEXT: [[ADD2:%.*]] = add i8 [[ADD]], [[L34]] 2226; TUNIT-NEXT: ret i8 [[ADD2]] 2227; 2228; CGSCC: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn 2229; CGSCC-LABEL: define {{[^@]+}}@phi_no_store_3 2230; CGSCC-SAME: () #[[ATTR5]] { 2231; CGSCC-NEXT: entry: 2232; CGSCC-NEXT: [[S30:%.*]] = getelementptr i8, ptr @a3, i64 3 2233; CGSCC-NEXT: store i8 0, ptr [[S30]], align 1 2234; CGSCC-NEXT: br label [[LOOP:%.*]] 2235; CGSCC: loop: 2236; CGSCC-NEXT: [[P:%.*]] = phi ptr [ @a3, [[ENTRY:%.*]] ], [ [[G:%.*]], [[LOOP]] ] 2237; CGSCC-NEXT: [[I:%.*]] = phi i8 [ 0, [[ENTRY]] ], [ [[O:%.*]], [[LOOP]] ] 2238; CGSCC-NEXT: store i8 1, ptr [[P]], align 1 2239; CGSCC-NEXT: [[G]] = getelementptr i8, ptr @a3, i64 2 2240; CGSCC-NEXT: [[O]] = add nsw i8 [[I]], 1 2241; CGSCC-NEXT: [[C:%.*]] = icmp eq i8 [[O]], 7 2242; CGSCC-NEXT: br i1 [[C]], label [[END:%.*]], label [[LOOP]] 2243; CGSCC: end: 2244; CGSCC-NEXT: [[S31:%.*]] = getelementptr i8, ptr @a3, i64 2 2245; CGSCC-NEXT: [[L31:%.*]] = load i8, ptr [[S31]], align 2 2246; CGSCC-NEXT: [[S32:%.*]] = getelementptr i8, ptr @a3, i64 3 2247; CGSCC-NEXT: [[L32:%.*]] = load i8, ptr [[S32]], align 1 2248; CGSCC-NEXT: [[ADD:%.*]] = add i8 [[L31]], [[L32]] 2249; CGSCC-NEXT: [[S34:%.*]] = getelementptr i8, ptr @a3, i64 4 2250; CGSCC-NEXT: [[L34:%.*]] = load i8, ptr [[S34]], align 4 2251; CGSCC-NEXT: [[ADD2:%.*]] = add i8 [[ADD]], [[L34]] 2252; CGSCC-NEXT: ret i8 [[ADD2]] 2253; 2254entry: 2255 %s30 = getelementptr i8, ptr @a3, i64 3 2256 store i8 0, ptr %s30 2257 br label %loop 2258loop: 2259 %p = phi ptr [@a3, %entry], [%g, %loop] 2260 %i = phi i8 [0, %entry], [%o, %loop] 2261 store i8 1, ptr %p 2262 %g = getelementptr i8, ptr @a3, i64 2 2263 %o = add nsw i8 %i, 1 2264 %c = icmp eq i8 %o, 7 2265 br i1 %c, label %end, label %loop 2266end: 2267 %s31 = getelementptr i8, ptr @a3, i64 2 2268 %l31 = load i8, ptr %s31 2269 %s32 = getelementptr i8, ptr @a3, i64 3 2270 %l32 = load i8, ptr %s32 2271 %add = add i8 %l31, %l32 2272 %s34 = getelementptr i8, ptr @a3, i64 4 2273 %l34 = load i8, ptr %s34 2274 %add2 = add i8 %add, %l34 2275 ret i8 %add2 2276} 2277 2278define i8 @cast_and_load_1() { 2279; TUNIT: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn 2280; TUNIT-LABEL: define {{[^@]+}}@cast_and_load_1 2281; TUNIT-SAME: () #[[ATTR3]] { 2282; TUNIT-NEXT: store i32 42, ptr @bytes1, align 4 2283; TUNIT-NEXT: [[L:%.*]] = load i8, ptr @bytes1, align 4 2284; TUNIT-NEXT: ret i8 [[L]] 2285; 2286; CGSCC: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn 2287; CGSCC-LABEL: define {{[^@]+}}@cast_and_load_1 2288; CGSCC-SAME: () #[[ATTR5]] { 2289; CGSCC-NEXT: store i32 42, ptr @bytes1, align 4 2290; CGSCC-NEXT: [[L:%.*]] = load i8, ptr @bytes1, align 4 2291; CGSCC-NEXT: ret i8 [[L]] 2292; 2293 store i32 42, ptr @bytes1 2294 %l = load i8, ptr @bytes1 2295 ret i8 %l 2296} 2297 2298define i64 @cast_and_load_2() { 2299; TUNIT: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn 2300; TUNIT-LABEL: define {{[^@]+}}@cast_and_load_2 2301; TUNIT-SAME: () #[[ATTR3]] { 2302; TUNIT-NEXT: store i32 42, ptr @bytes2, align 4 2303; TUNIT-NEXT: [[L:%.*]] = load i64, ptr @bytes2, align 4 2304; TUNIT-NEXT: ret i64 [[L]] 2305; 2306; CGSCC: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn 2307; CGSCC-LABEL: define {{[^@]+}}@cast_and_load_2 2308; CGSCC-SAME: () #[[ATTR5]] { 2309; CGSCC-NEXT: store i32 42, ptr @bytes2, align 4 2310; CGSCC-NEXT: [[L:%.*]] = load i64, ptr @bytes2, align 4 2311; CGSCC-NEXT: ret i64 [[L]] 2312; 2313 store i32 42, ptr @bytes2 2314 %l = load i64, ptr @bytes2 2315 ret i64 %l 2316} 2317 2318define void @recursive_load_store(i64 %N, i32 %v) { 2319; 2320; TUNIT: Function Attrs: nofree norecurse nosync nounwind memory(write) 2321; TUNIT-LABEL: define {{[^@]+}}@recursive_load_store 2322; TUNIT-SAME: (i64 [[N:%.*]], i32 [[V:%.*]]) #[[ATTR7:[0-9]+]] { 2323; TUNIT-NEXT: entry: 2324; TUNIT-NEXT: br label [[FOR_COND:%.*]] 2325; TUNIT: for.cond: 2326; TUNIT-NEXT: [[INDVARS_IV:%.*]] = phi i64 [ [[INDVARS_IV_NEXT:%.*]], [[FOR_BODY:%.*]] ], [ 0, [[ENTRY:%.*]] ] 2327; TUNIT-NEXT: [[EXITCOND:%.*]] = icmp ne i64 [[INDVARS_IV]], [[N]] 2328; TUNIT-NEXT: br i1 [[EXITCOND]], label [[FOR_BODY]], label [[FOR_END:%.*]] 2329; TUNIT: for.body: 2330; TUNIT-NEXT: [[INDVARS_IV_NEXT]] = add nuw nsw i64 [[INDVARS_IV]], 1 2331; TUNIT-NEXT: br label [[FOR_COND]] 2332; TUNIT: for.end: 2333; TUNIT-NEXT: ret void 2334; 2335; CGSCC: Function Attrs: nofree norecurse nosync nounwind memory(write) 2336; CGSCC-LABEL: define {{[^@]+}}@recursive_load_store 2337; CGSCC-SAME: (i64 [[N:%.*]], i32 [[V:%.*]]) #[[ATTR8:[0-9]+]] { 2338; CGSCC-NEXT: entry: 2339; CGSCC-NEXT: br label [[FOR_COND:%.*]] 2340; CGSCC: for.cond: 2341; CGSCC-NEXT: [[INDVARS_IV:%.*]] = phi i64 [ [[INDVARS_IV_NEXT:%.*]], [[FOR_BODY:%.*]] ], [ 0, [[ENTRY:%.*]] ] 2342; CGSCC-NEXT: [[EXITCOND:%.*]] = icmp ne i64 [[INDVARS_IV]], [[N]] 2343; CGSCC-NEXT: br i1 [[EXITCOND]], label [[FOR_BODY]], label [[FOR_END:%.*]] 2344; CGSCC: for.body: 2345; CGSCC-NEXT: [[INDVARS_IV_NEXT]] = add nuw nsw i64 [[INDVARS_IV]], 1 2346; CGSCC-NEXT: br label [[FOR_COND]] 2347; CGSCC: for.end: 2348; CGSCC-NEXT: ret void 2349; 2350entry: 2351 store i32 %v, ptr @rec_storage 2352 br label %for.cond 2353 2354for.cond: 2355 %indvars.iv = phi i64 [ %indvars.iv.next, %for.body ], [ 0, %entry ] 2356 %exitcond = icmp ne i64 %indvars.iv, %N 2357 br i1 %exitcond, label %for.body, label %for.end 2358 2359for.body: 2360 %ll = load i32, ptr @rec_storage 2361 store i32 %ll, ptr @rec_storage 2362 %indvars.iv.next = add nuw nsw i64 %indvars.iv, 1 2363 br label %for.cond 2364 2365for.end: 2366 %lr = load i32, ptr @rec_storage 2367 store i32 %lr, ptr @rec_storage 2368 ret void 2369} 2370 2371define dso_local i32 @round_trip_malloc(i32 %x) { 2372; CHECK-LABEL: define {{[^@]+}}@round_trip_malloc 2373; CHECK-SAME: (i32 returned [[X:%.*]]) { 2374; CHECK-NEXT: entry: 2375; CHECK-NEXT: [[CALL_H2S:%.*]] = alloca i8, i64 4, align 1 2376; CHECK-NEXT: store i32 [[X]], ptr [[CALL_H2S]], align 4 2377; CHECK-NEXT: ret i32 [[X]] 2378; 2379entry: 2380 %call = call noalias ptr @malloc(i64 4) norecurse 2381 store i32 %x, ptr %call, align 4 2382 %0 = load i32, ptr %call, align 4 2383 call void @free(ptr %call) norecurse 2384 ret i32 %0 2385} 2386 2387define dso_local i32 @round_trip_malloc_constant() { 2388; CHECK-LABEL: define {{[^@]+}}@round_trip_malloc_constant() { 2389; CHECK-NEXT: entry: 2390; CHECK-NEXT: ret i32 7 2391; 2392entry: 2393 %call = call noalias ptr @malloc(i64 4) norecurse 2394 store i32 7, ptr %call, align 4 2395 %0 = load i32, ptr %call, align 4 2396 call void @free(ptr %call) norecurse 2397 ret i32 %0 2398} 2399 2400declare noalias ptr @malloc(i64) allockind("alloc,uninitialized") allocsize(0) "alloc-family"="malloc" 2401 2402declare void @free(ptr) allockind("free") "alloc-family"="malloc" 2403 2404define dso_local i32 @conditional_malloc(i32 %x) { 2405; CHECK-LABEL: define {{[^@]+}}@conditional_malloc 2406; CHECK-SAME: (i32 returned [[X:%.*]]) { 2407; CHECK-NEXT: entry: 2408; CHECK-NEXT: [[CALL_H2S:%.*]] = alloca i8, i64 4, align 1 2409; CHECK-NEXT: [[TOBOOL:%.*]] = icmp ne i32 [[X]], 0 2410; CHECK-NEXT: br i1 [[TOBOOL]], label [[IF_THEN:%.*]], label [[IF_END:%.*]] 2411; CHECK: if.then: 2412; CHECK-NEXT: store i32 [[X]], ptr [[CALL_H2S]], align 4 2413; CHECK-NEXT: br label [[IF_END]] 2414; CHECK: if.end: 2415; CHECK-NEXT: ret i32 [[X]] 2416; 2417entry: 2418 %call = call noalias ptr @malloc(i64 4) norecurse 2419 %tobool = icmp ne i32 %x, 0 2420 br i1 %tobool, label %if.then, label %if.end 2421 2422if.then: ; preds = %entry 2423 store i32 %x, ptr %call, align 4 2424 br label %if.end 2425 2426if.end: ; preds = %if.then, %entry 2427 %0 = load i32, ptr %call, align 4 2428 ret i32 %0 2429} 2430 2431define dso_local i32 @round_trip_calloc(i32 %x) { 2432; CHECK-LABEL: define {{[^@]+}}@round_trip_calloc 2433; CHECK-SAME: (i32 returned [[X:%.*]]) { 2434; CHECK-NEXT: entry: 2435; CHECK-NEXT: [[CALL_H2S:%.*]] = alloca i8, i64 4, align 1 2436; CHECK-NEXT: call void @llvm.memset.p0.i64(ptr [[CALL_H2S]], i8 0, i64 4, i1 false) 2437; CHECK-NEXT: store i32 [[X]], ptr [[CALL_H2S]], align 4 2438; CHECK-NEXT: ret i32 [[X]] 2439; 2440entry: 2441 %call = call noalias ptr @calloc(i64 4, i64 1) norecurse 2442 store i32 %x, ptr %call, align 4 2443 %0 = load i32, ptr %call, align 4 2444 ret i32 %0 2445} 2446 2447define dso_local i32 @round_trip_calloc_constant() { 2448; CHECK-LABEL: define {{[^@]+}}@round_trip_calloc_constant() { 2449; CHECK-NEXT: entry: 2450; CHECK-NEXT: [[CALL_H2S:%.*]] = alloca i8, i64 4, align 1 2451; CHECK-NEXT: call void @llvm.memset.p0.i64(ptr [[CALL_H2S]], i8 0, i64 4, i1 false) 2452; CHECK-NEXT: ret i32 11 2453; 2454entry: 2455 %call = call noalias ptr @calloc(i64 4, i64 1) norecurse 2456 store i32 11, ptr %call, align 4 2457 %0 = load i32, ptr %call, align 4 2458 ret i32 %0 2459} 2460 2461declare noalias ptr @calloc(i64, i64) allockind("alloc,zeroed") allocsize(0, 1) "alloc-family"="malloc" 2462 2463define dso_local i32 @conditional_calloc(i32 %x) { 2464; CHECK-LABEL: define {{[^@]+}}@conditional_calloc 2465; CHECK-SAME: (i32 [[X:%.*]]) { 2466; CHECK-NEXT: entry: 2467; CHECK-NEXT: [[CALL_H2S:%.*]] = alloca i8, i64 4, align 1 2468; CHECK-NEXT: call void @llvm.memset.p0.i64(ptr [[CALL_H2S]], i8 0, i64 4, i1 false) 2469; CHECK-NEXT: [[TOBOOL:%.*]] = icmp ne i32 [[X]], 0 2470; CHECK-NEXT: br i1 [[TOBOOL]], label [[IF_END:%.*]], label [[IF_THEN:%.*]] 2471; CHECK: if.then: 2472; CHECK-NEXT: store i32 [[X]], ptr [[CALL_H2S]], align 4 2473; CHECK-NEXT: br label [[IF_END]] 2474; CHECK: if.end: 2475; CHECK-NEXT: [[TMP0:%.*]] = load i32, ptr [[CALL_H2S]], align 4 2476; CHECK-NEXT: ret i32 [[TMP0]] 2477; 2478entry: 2479 %call = call noalias ptr @calloc(i64 1, i64 4) norecurse 2480 %tobool = icmp ne i32 %x, 0 2481 br i1 %tobool, label %if.end, label %if.then 2482 2483if.then: ; preds = %entry 2484 store i32 %x, ptr %call, align 4 2485 br label %if.end 2486 2487if.end: ; preds = %if.then, %entry 2488 %0 = load i32, ptr %call, align 4 2489 call void @free(ptr %call) norecurse 2490 ret i32 %0 2491} 2492 2493define dso_local i32 @conditional_calloc_zero(i1 %c) { 2494; CHECK-LABEL: define {{[^@]+}}@conditional_calloc_zero 2495; CHECK-SAME: (i1 [[C:%.*]]) { 2496; CHECK-NEXT: entry: 2497; CHECK-NEXT: [[CALL_H2S:%.*]] = alloca i8, i64 4, align 1 2498; CHECK-NEXT: call void @llvm.memset.p0.i64(ptr [[CALL_H2S]], i8 0, i64 4, i1 false) 2499; CHECK-NEXT: br i1 [[C]], label [[IF_END:%.*]], label [[IF_THEN:%.*]] 2500; CHECK: if.then: 2501; CHECK-NEXT: br label [[IF_END]] 2502; CHECK: if.end: 2503; CHECK-NEXT: ret i32 0 2504; 2505entry: 2506 %call = call noalias ptr @calloc(i64 1, i64 4) norecurse 2507 br i1 %c, label %if.end, label %if.then 2508 2509if.then: ; preds = %entry 2510 store i32 0, ptr %call, align 4 2511 br label %if.end 2512 2513if.end: ; preds = %if.then, %entry 2514 %0 = load i32, ptr %call, align 4 2515 call void @free(ptr %call) norecurse 2516 ret i32 %0 2517} 2518 2519define dso_local ptr @malloc_like(i32 %s) { 2520; TUNIT-LABEL: define {{[^@]+}}@malloc_like 2521; TUNIT-SAME: (i32 [[S:%.*]]) { 2522; TUNIT-NEXT: entry: 2523; TUNIT-NEXT: [[CONV:%.*]] = sext i32 [[S]] to i64 2524; TUNIT-NEXT: [[CALL:%.*]] = call noalias ptr @malloc(i64 [[CONV]]) #[[ATTR20:[0-9]+]] 2525; TUNIT-NEXT: ret ptr [[CALL]] 2526; 2527; CGSCC-LABEL: define {{[^@]+}}@malloc_like 2528; CGSCC-SAME: (i32 [[S:%.*]]) { 2529; CGSCC-NEXT: entry: 2530; CGSCC-NEXT: [[CONV:%.*]] = sext i32 [[S]] to i64 2531; CGSCC-NEXT: [[CALL:%.*]] = call noalias ptr @malloc(i64 [[CONV]]) #[[ATTR23:[0-9]+]] 2532; CGSCC-NEXT: ret ptr [[CALL]] 2533; 2534entry: 2535 %conv = sext i32 %s to i64 2536 %call = call noalias ptr @malloc(i64 %conv) norecurse 2537 ret ptr %call 2538} 2539 2540define dso_local i32 @round_trip_malloc_like(i32 %x) { 2541; TUNIT-LABEL: define {{[^@]+}}@round_trip_malloc_like 2542; TUNIT-SAME: (i32 [[X:%.*]]) { 2543; TUNIT-NEXT: entry: 2544; TUNIT-NEXT: [[CALL:%.*]] = call noalias ptr @malloc_like(i32 noundef 4) #[[ATTR20]] 2545; TUNIT-NEXT: store i32 [[X]], ptr [[CALL]], align 4 2546; TUNIT-NEXT: [[TMP0:%.*]] = load i32, ptr [[CALL]], align 4 2547; TUNIT-NEXT: call void @free(ptr noundef nonnull align 4 dereferenceable(4) [[CALL]]) #[[ATTR20]] 2548; TUNIT-NEXT: ret i32 [[TMP0]] 2549; 2550; CGSCC-LABEL: define {{[^@]+}}@round_trip_malloc_like 2551; CGSCC-SAME: (i32 [[X:%.*]]) { 2552; CGSCC-NEXT: entry: 2553; CGSCC-NEXT: [[CALL:%.*]] = call noalias ptr @malloc_like(i32 noundef 4) #[[ATTR23]] 2554; CGSCC-NEXT: store i32 [[X]], ptr [[CALL]], align 4 2555; CGSCC-NEXT: [[TMP0:%.*]] = load i32, ptr [[CALL]], align 4 2556; CGSCC-NEXT: call void @free(ptr noundef nonnull align 4 dereferenceable(4) [[CALL]]) #[[ATTR23]] 2557; CGSCC-NEXT: ret i32 [[TMP0]] 2558; 2559entry: 2560 %call = call ptr @malloc_like(i32 4) norecurse 2561 store i32 %x, ptr %call, align 4 2562 %0 = load i32, ptr %call, align 4 2563 call void @free(ptr %call) norecurse 2564 ret i32 %0 2565} 2566 2567define dso_local i32 @round_trip_unknown_alloc(i32 %x) { 2568; TUNIT-LABEL: define {{[^@]+}}@round_trip_unknown_alloc 2569; TUNIT-SAME: (i32 [[X:%.*]]) { 2570; TUNIT-NEXT: entry: 2571; TUNIT-NEXT: [[CALL:%.*]] = call noalias ptr @unknown_alloc(i32 noundef 4) #[[ATTR20]] 2572; TUNIT-NEXT: store i32 [[X]], ptr [[CALL]], align 4 2573; TUNIT-NEXT: [[TMP0:%.*]] = load i32, ptr [[CALL]], align 4 2574; TUNIT-NEXT: call void @free(ptr noundef nonnull align 4 dereferenceable(4) [[CALL]]) #[[ATTR20]] 2575; TUNIT-NEXT: ret i32 [[TMP0]] 2576; 2577; CGSCC-LABEL: define {{[^@]+}}@round_trip_unknown_alloc 2578; CGSCC-SAME: (i32 [[X:%.*]]) { 2579; CGSCC-NEXT: entry: 2580; CGSCC-NEXT: [[CALL:%.*]] = call noalias ptr @unknown_alloc(i32 noundef 4) #[[ATTR23]] 2581; CGSCC-NEXT: store i32 [[X]], ptr [[CALL]], align 4 2582; CGSCC-NEXT: [[TMP0:%.*]] = load i32, ptr [[CALL]], align 4 2583; CGSCC-NEXT: call void @free(ptr noundef nonnull align 4 dereferenceable(4) [[CALL]]) #[[ATTR23]] 2584; CGSCC-NEXT: ret i32 [[TMP0]] 2585; 2586entry: 2587 %call = call ptr @unknown_alloc(i32 4) norecurse 2588 store i32 %x, ptr %call, align 4 2589 %0 = load i32, ptr %call, align 4 2590 call void @free(ptr %call) norecurse 2591 ret i32 %0 2592} 2593 2594declare noalias ptr @unknown_alloc(i32) 2595 2596define dso_local i32 @conditional_unknown_alloc(i32 %x) { 2597; TUNIT-LABEL: define {{[^@]+}}@conditional_unknown_alloc 2598; TUNIT-SAME: (i32 [[X:%.*]]) { 2599; TUNIT-NEXT: entry: 2600; TUNIT-NEXT: [[CALL:%.*]] = call noalias ptr @unknown_alloc(i32 noundef 4) #[[ATTR20]] 2601; TUNIT-NEXT: [[TOBOOL:%.*]] = icmp ne i32 [[X]], 0 2602; TUNIT-NEXT: br i1 [[TOBOOL]], label [[IF_END:%.*]], label [[IF_THEN:%.*]] 2603; TUNIT: if.then: 2604; TUNIT-NEXT: store i32 [[X]], ptr [[CALL]], align 4 2605; TUNIT-NEXT: br label [[IF_END]] 2606; TUNIT: if.end: 2607; TUNIT-NEXT: [[TMP0:%.*]] = load i32, ptr [[CALL]], align 4 2608; TUNIT-NEXT: call void @free(ptr nonnull align 4 dereferenceable(4) [[CALL]]) #[[ATTR20]] 2609; TUNIT-NEXT: ret i32 [[TMP0]] 2610; 2611; CGSCC-LABEL: define {{[^@]+}}@conditional_unknown_alloc 2612; CGSCC-SAME: (i32 [[X:%.*]]) { 2613; CGSCC-NEXT: entry: 2614; CGSCC-NEXT: [[CALL:%.*]] = call noalias ptr @unknown_alloc(i32 noundef 4) #[[ATTR23]] 2615; CGSCC-NEXT: [[TOBOOL:%.*]] = icmp ne i32 [[X]], 0 2616; CGSCC-NEXT: br i1 [[TOBOOL]], label [[IF_END:%.*]], label [[IF_THEN:%.*]] 2617; CGSCC: if.then: 2618; CGSCC-NEXT: store i32 [[X]], ptr [[CALL]], align 4 2619; CGSCC-NEXT: br label [[IF_END]] 2620; CGSCC: if.end: 2621; CGSCC-NEXT: [[TMP0:%.*]] = load i32, ptr [[CALL]], align 4 2622; CGSCC-NEXT: call void @free(ptr nonnull align 4 dereferenceable(4) [[CALL]]) #[[ATTR23]] 2623; CGSCC-NEXT: ret i32 [[TMP0]] 2624; 2625entry: 2626 %call = call noalias ptr @unknown_alloc(i32 4) norecurse 2627 %tobool = icmp ne i32 %x, 0 2628 br i1 %tobool, label %if.end, label %if.then 2629 2630if.then: ; preds = %entry 2631 store i32 %x, ptr %call, align 4 2632 br label %if.end 2633 2634if.end: ; preds = %if.then, %entry 2635 %0 = load i32, ptr %call, align 4 2636 call void @free(ptr %call) norecurse 2637 ret i32 %0 2638} 2639 2640%struct.STy = type { ptr, ptr, ptr } 2641 2642@global = internal global %struct.STy zeroinitializer, align 8 2643 2644; We mark %dst as writeonly and %src as readonly, that is (for now) all we can expect. 2645define dso_local void @test_nested_memory(ptr %dst, ptr %src) { 2646; TUNIT-LABEL: define {{[^@]+}}@test_nested_memory 2647; TUNIT-SAME: (ptr nofree writeonly captures(none) [[DST:%.*]], ptr nofree readonly captures(none) [[SRC:%.*]]) { 2648; TUNIT-NEXT: entry: 2649; TUNIT-NEXT: [[CALL_H2S:%.*]] = alloca i8, i64 24, align 1 2650; TUNIT-NEXT: [[LOCAL:%.*]] = alloca [[STRUCT_STY:%.*]], align 8 2651; TUNIT-NEXT: [[INNER:%.*]] = getelementptr inbounds [[STRUCT_STY]], ptr [[LOCAL]], i64 0, i32 2 2652; TUNIT-NEXT: store ptr @global, ptr [[INNER]], align 8 2653; TUNIT-NEXT: store ptr [[DST]], ptr [[CALL_H2S]], align 8 2654; TUNIT-NEXT: [[SRC2:%.*]] = getelementptr inbounds i8, ptr [[CALL_H2S]], i64 8 2655; TUNIT-NEXT: store ptr [[SRC]], ptr [[SRC2]], align 8 2656; TUNIT-NEXT: store ptr [[CALL_H2S]], ptr getelementptr inbounds ([[STRUCT_STY]], ptr @global, i64 0, i32 2), align 8 2657; TUNIT-NEXT: [[TMP0:%.*]] = load ptr, ptr [[LOCAL]], align 8 2658; TUNIT-NEXT: [[LOCAL_B8:%.*]] = getelementptr i8, ptr [[LOCAL]], i64 8 2659; TUNIT-NEXT: [[TMP1:%.*]] = load ptr, ptr [[LOCAL_B8]], align 8 2660; TUNIT-NEXT: [[LOCAL_B16:%.*]] = getelementptr i8, ptr [[LOCAL]], i64 16 2661; TUNIT-NEXT: [[TMP2:%.*]] = load ptr, ptr [[LOCAL_B16]], align 8 2662; TUNIT-NEXT: call fastcc void @nested_memory_callee(ptr [[TMP0]], ptr [[TMP1]], ptr [[TMP2]]) #[[ATTR21:[0-9]+]] 2663; TUNIT-NEXT: ret void 2664; 2665; CGSCC-LABEL: define {{[^@]+}}@test_nested_memory 2666; CGSCC-SAME: (ptr nofree [[DST:%.*]], ptr nofree [[SRC:%.*]]) { 2667; CGSCC-NEXT: entry: 2668; CGSCC-NEXT: [[LOCAL:%.*]] = alloca [[STRUCT_STY:%.*]], align 8 2669; CGSCC-NEXT: [[INNER:%.*]] = getelementptr inbounds [[STRUCT_STY]], ptr [[LOCAL]], i64 0, i32 2 2670; CGSCC-NEXT: [[CALL:%.*]] = call noalias dereferenceable_or_null(24) ptr @malloc(i64 noundef 24) 2671; CGSCC-NEXT: store ptr [[DST]], ptr [[CALL]], align 8 2672; CGSCC-NEXT: [[SRC2:%.*]] = getelementptr inbounds i8, ptr [[CALL]], i64 8 2673; CGSCC-NEXT: store ptr [[SRC]], ptr [[SRC2]], align 8 2674; CGSCC-NEXT: store ptr [[CALL]], ptr getelementptr inbounds ([[STRUCT_STY]], ptr @global, i64 0, i32 2), align 8 2675; CGSCC-NEXT: call fastcc void @nested_memory_callee(ptr nofree align 4294967296 undef, ptr nofree align 4294967296 undef, ptr nofree noundef nonnull align 8 dereferenceable(24) @global) #[[ATTR24:[0-9]+]] 2676; CGSCC-NEXT: ret void 2677; 2678entry: 2679 %local = alloca %struct.STy, align 8 2680 %inner = getelementptr inbounds %struct.STy, ptr %local, i64 0, i32 2 2681 store ptr @global, ptr %inner, align 8 2682 %call = call noalias dereferenceable_or_null(24) ptr @malloc(i64 24) #4 2683 store ptr %dst, ptr %call, align 8 2684 %src2 = getelementptr inbounds i8, ptr %call, i64 8 2685 store ptr %src, ptr %src2, align 8 2686 store ptr %call, ptr getelementptr inbounds (%struct.STy, ptr @global, i64 0, i32 2), align 8 2687 call fastcc void @nested_memory_callee(ptr nonnull %local) 2688 ret void 2689} 2690 2691define internal fastcc void @nested_memory_callee(ptr nocapture readonly %S) nofree norecurse nounwind uwtable { 2692; TUNIT: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn uwtable 2693; TUNIT-LABEL: define {{[^@]+}}@nested_memory_callee 2694; TUNIT-SAME: (ptr [[TMP0:%.*]], ptr [[TMP1:%.*]], ptr [[TMP2:%.*]]) #[[ATTR11:[0-9]+]] { 2695; TUNIT-NEXT: entry: 2696; TUNIT-NEXT: [[S_PRIV:%.*]] = alloca [[STRUCT_STY:%.*]], align 8 2697; TUNIT-NEXT: store ptr [[TMP0]], ptr [[S_PRIV]], align 8 2698; TUNIT-NEXT: [[S_PRIV_B8:%.*]] = getelementptr i8, ptr [[S_PRIV]], i64 8 2699; TUNIT-NEXT: store ptr [[TMP1]], ptr [[S_PRIV_B8]], align 8 2700; TUNIT-NEXT: [[S_PRIV_B16:%.*]] = getelementptr i8, ptr [[S_PRIV]], i64 16 2701; TUNIT-NEXT: store ptr [[TMP2]], ptr [[S_PRIV_B16]], align 8 2702; TUNIT-NEXT: [[INNER:%.*]] = getelementptr inbounds [[STRUCT_STY]], ptr [[S_PRIV]], i64 0, i32 2 2703; TUNIT-NEXT: [[TMP3:%.*]] = load ptr, ptr [[INNER]], align 8 2704; TUNIT-NEXT: [[INNER1:%.*]] = getelementptr inbounds [[STRUCT_STY]], ptr [[TMP3]], i64 0, i32 2 2705; TUNIT-NEXT: [[TMP4:%.*]] = load ptr, ptr [[INNER1]], align 8 2706; TUNIT-NEXT: [[SRC:%.*]] = getelementptr inbounds [[STRUCT_STY]], ptr [[TMP4]], i64 0, i32 1 2707; TUNIT-NEXT: [[TMP5:%.*]] = load ptr, ptr [[SRC]], align 8 2708; TUNIT-NEXT: [[TMP6:%.*]] = load double, ptr [[TMP5]], align 8 2709; TUNIT-NEXT: [[CONV:%.*]] = fptrunc double [[TMP6]] to float 2710; TUNIT-NEXT: [[TMP7:%.*]] = load ptr, ptr [[TMP4]], align 8 2711; TUNIT-NEXT: store float [[CONV]], ptr [[TMP7]], align 4 2712; TUNIT-NEXT: ret void 2713; 2714; CGSCC: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn uwtable 2715; CGSCC-LABEL: define {{[^@]+}}@nested_memory_callee 2716; CGSCC-SAME: (ptr nofree [[TMP0:%.*]], ptr nofree [[TMP1:%.*]], ptr nofree [[TMP2:%.*]]) #[[ATTR12:[0-9]+]] { 2717; CGSCC-NEXT: entry: 2718; CGSCC-NEXT: [[S_PRIV:%.*]] = alloca [[STRUCT_STY:%.*]], align 8 2719; CGSCC-NEXT: store ptr [[TMP0]], ptr [[S_PRIV]], align 8 2720; CGSCC-NEXT: [[S_PRIV_B8:%.*]] = getelementptr i8, ptr [[S_PRIV]], i64 8 2721; CGSCC-NEXT: store ptr [[TMP1]], ptr [[S_PRIV_B8]], align 8 2722; CGSCC-NEXT: [[S_PRIV_B16:%.*]] = getelementptr i8, ptr [[S_PRIV]], i64 16 2723; CGSCC-NEXT: store ptr [[TMP2]], ptr [[S_PRIV_B16]], align 8 2724; CGSCC-NEXT: [[INNER:%.*]] = getelementptr inbounds [[STRUCT_STY]], ptr [[S_PRIV]], i64 0, i32 2 2725; CGSCC-NEXT: [[TMP3:%.*]] = load ptr, ptr [[INNER]], align 8 2726; CGSCC-NEXT: [[INNER1:%.*]] = getelementptr inbounds [[STRUCT_STY]], ptr [[TMP3]], i64 0, i32 2 2727; CGSCC-NEXT: [[TMP4:%.*]] = load ptr, ptr [[INNER1]], align 8 2728; CGSCC-NEXT: [[SRC:%.*]] = getelementptr inbounds [[STRUCT_STY]], ptr [[TMP4]], i64 0, i32 1 2729; CGSCC-NEXT: [[TMP5:%.*]] = load ptr, ptr [[SRC]], align 8 2730; CGSCC-NEXT: [[TMP6:%.*]] = load double, ptr [[TMP5]], align 8 2731; CGSCC-NEXT: [[CONV:%.*]] = fptrunc double [[TMP6]] to float 2732; CGSCC-NEXT: [[TMP7:%.*]] = load ptr, ptr [[TMP4]], align 8 2733; CGSCC-NEXT: store float [[CONV]], ptr [[TMP7]], align 4 2734; CGSCC-NEXT: ret void 2735; 2736entry: 2737 %inner = getelementptr inbounds %struct.STy, ptr %S, i64 0, i32 2 2738 %0 = load ptr, ptr %inner, align 8 2739 %inner1 = getelementptr inbounds %struct.STy, ptr %0, i64 0, i32 2 2740 %1 = load ptr, ptr %inner1, align 8 2741 %src = getelementptr inbounds %struct.STy, ptr %1, i64 0, i32 1 2742 %2 = load ptr, ptr %src, align 8 2743 %3 = load double, ptr %2, align 8 2744 %conv = fptrunc double %3 to float 2745 %4 = load ptr, ptr %1, align 8 2746 store float %conv, ptr %4, align 4 2747 ret void 2748} 2749 2750; Make sure the access %1 is not forwarded to the loads %2 and %3 as the indices are 2751; varying and the accesses thus not "exact". This used to simplify %cmp12 to true. 2752define hidden void @no_propagation_of_unknown_index_access(ptr %in, ptr %out, i32 %idx) #0 { 2753; TUNIT: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(argmem: readwrite) 2754; TUNIT-LABEL: define {{[^@]+}}@no_propagation_of_unknown_index_access 2755; TUNIT-SAME: (ptr nofree readonly captures(none) [[IN:%.*]], ptr nofree writeonly captures(none) [[OUT:%.*]], i32 [[IDX:%.*]]) #[[ATTR1]] { 2756; TUNIT-NEXT: entry: 2757; TUNIT-NEXT: [[BUF:%.*]] = alloca [128 x i32], align 16 2758; TUNIT-NEXT: call void @llvm.lifetime.start.p0(i64 noundef 512, ptr noalias nofree noundef nonnull align 16 captures(none) dereferenceable(512) [[BUF]]) #[[ATTR17]] 2759; TUNIT-NEXT: br label [[FOR_COND:%.*]] 2760; TUNIT: for.cond: 2761; TUNIT-NEXT: [[I_0:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[INC:%.*]], [[FOR_BODY:%.*]] ] 2762; TUNIT-NEXT: [[CMP:%.*]] = icmp slt i32 [[I_0]], 128 2763; TUNIT-NEXT: br i1 [[CMP]], label [[FOR_BODY]], label [[FOR_COND_CLEANUP:%.*]] 2764; TUNIT: for.cond.cleanup: 2765; TUNIT-NEXT: br label [[FOR_COND4:%.*]] 2766; TUNIT: for.body: 2767; TUNIT-NEXT: [[IDXPROM:%.*]] = sext i32 [[I_0]] to i64 2768; TUNIT-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds i32, ptr [[IN]], i64 [[IDXPROM]] 2769; TUNIT-NEXT: [[TMP0:%.*]] = load i32, ptr [[ARRAYIDX]], align 4 2770; TUNIT-NEXT: [[ARRAYIDX2:%.*]] = getelementptr inbounds [128 x i32], ptr [[BUF]], i64 0, i64 [[IDXPROM]] 2771; TUNIT-NEXT: store i32 [[TMP0]], ptr [[ARRAYIDX2]], align 4 2772; TUNIT-NEXT: [[INC]] = add nsw i32 [[I_0]], 1 2773; TUNIT-NEXT: br label [[FOR_COND]], !llvm.loop [[TBAA10]] 2774; TUNIT: for.cond4: 2775; TUNIT-NEXT: [[I3_0:%.*]] = phi i32 [ 0, [[FOR_COND_CLEANUP]] ], [ [[INC16:%.*]], [[FOR_BODY7:%.*]] ] 2776; TUNIT-NEXT: [[CMP5:%.*]] = icmp slt i32 [[I3_0]], 128 2777; TUNIT-NEXT: br i1 [[CMP5]], label [[FOR_BODY7]], label [[FOR_COND_CLEANUP6:%.*]] 2778; TUNIT: for.cond.cleanup6: 2779; TUNIT-NEXT: call void @llvm.lifetime.end.p0(i64 noundef 512, ptr noalias nofree noundef nonnull align 16 captures(none) dereferenceable(512) [[BUF]]) #[[ATTR17]] 2780; TUNIT-NEXT: ret void 2781; TUNIT: for.body7: 2782; TUNIT-NEXT: [[IDXPROM8:%.*]] = sext i32 [[I3_0]] to i64 2783; TUNIT-NEXT: [[ARRAYIDX9:%.*]] = getelementptr inbounds [128 x i32], ptr [[BUF]], i64 0, i64 [[IDXPROM8]] 2784; TUNIT-NEXT: [[TMP1:%.*]] = load i32, ptr [[ARRAYIDX9]], align 4 2785; TUNIT-NEXT: [[IDXPROM10:%.*]] = sext i32 [[IDX]] to i64 2786; TUNIT-NEXT: [[ARRAYIDX11:%.*]] = getelementptr inbounds [128 x i32], ptr [[BUF]], i64 0, i64 [[IDXPROM10]] 2787; TUNIT-NEXT: [[TMP2:%.*]] = load i32, ptr [[ARRAYIDX11]], align 4 2788; TUNIT-NEXT: [[CMP12:%.*]] = icmp sle i32 [[TMP1]], [[TMP2]] 2789; TUNIT-NEXT: [[CONV:%.*]] = zext i1 [[CMP12]] to i32 2790; TUNIT-NEXT: [[ARRAYIDX14:%.*]] = getelementptr inbounds i32, ptr [[OUT]], i64 [[IDXPROM8]] 2791; TUNIT-NEXT: store i32 [[CONV]], ptr [[ARRAYIDX14]], align 4 2792; TUNIT-NEXT: [[INC16]] = add nsw i32 [[I3_0]], 1 2793; TUNIT-NEXT: br label [[FOR_COND4]], !llvm.loop [[TBAA12]] 2794; 2795; CGSCC: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(argmem: readwrite) 2796; CGSCC-LABEL: define {{[^@]+}}@no_propagation_of_unknown_index_access 2797; CGSCC-SAME: (ptr nofree readonly captures(none) [[IN:%.*]], ptr nofree writeonly captures(none) [[OUT:%.*]], i32 [[IDX:%.*]]) #[[ATTR13:[0-9]+]] { 2798; CGSCC-NEXT: entry: 2799; CGSCC-NEXT: [[BUF:%.*]] = alloca [128 x i32], align 16 2800; CGSCC-NEXT: call void @llvm.lifetime.start.p0(i64 noundef 512, ptr noalias nofree noundef nonnull align 16 captures(none) dereferenceable(512) [[BUF]]) #[[ATTR20]] 2801; CGSCC-NEXT: br label [[FOR_COND:%.*]] 2802; CGSCC: for.cond: 2803; CGSCC-NEXT: [[I_0:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[INC:%.*]], [[FOR_BODY:%.*]] ] 2804; CGSCC-NEXT: [[CMP:%.*]] = icmp slt i32 [[I_0]], 128 2805; CGSCC-NEXT: br i1 [[CMP]], label [[FOR_BODY]], label [[FOR_COND_CLEANUP:%.*]] 2806; CGSCC: for.cond.cleanup: 2807; CGSCC-NEXT: br label [[FOR_COND4:%.*]] 2808; CGSCC: for.body: 2809; CGSCC-NEXT: [[IDXPROM:%.*]] = sext i32 [[I_0]] to i64 2810; CGSCC-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds i32, ptr [[IN]], i64 [[IDXPROM]] 2811; CGSCC-NEXT: [[TMP0:%.*]] = load i32, ptr [[ARRAYIDX]], align 4 2812; CGSCC-NEXT: [[ARRAYIDX2:%.*]] = getelementptr inbounds [128 x i32], ptr [[BUF]], i64 0, i64 [[IDXPROM]] 2813; CGSCC-NEXT: store i32 [[TMP0]], ptr [[ARRAYIDX2]], align 4 2814; CGSCC-NEXT: [[INC]] = add nsw i32 [[I_0]], 1 2815; CGSCC-NEXT: br label [[FOR_COND]], !llvm.loop [[TBAA10]] 2816; CGSCC: for.cond4: 2817; CGSCC-NEXT: [[I3_0:%.*]] = phi i32 [ 0, [[FOR_COND_CLEANUP]] ], [ [[INC16:%.*]], [[FOR_BODY7:%.*]] ] 2818; CGSCC-NEXT: [[CMP5:%.*]] = icmp slt i32 [[I3_0]], 128 2819; CGSCC-NEXT: br i1 [[CMP5]], label [[FOR_BODY7]], label [[FOR_COND_CLEANUP6:%.*]] 2820; CGSCC: for.cond.cleanup6: 2821; CGSCC-NEXT: call void @llvm.lifetime.end.p0(i64 noundef 512, ptr noalias nofree noundef nonnull align 16 captures(none) dereferenceable(512) [[BUF]]) #[[ATTR20]] 2822; CGSCC-NEXT: ret void 2823; CGSCC: for.body7: 2824; CGSCC-NEXT: [[IDXPROM8:%.*]] = sext i32 [[I3_0]] to i64 2825; CGSCC-NEXT: [[ARRAYIDX9:%.*]] = getelementptr inbounds [128 x i32], ptr [[BUF]], i64 0, i64 [[IDXPROM8]] 2826; CGSCC-NEXT: [[TMP1:%.*]] = load i32, ptr [[ARRAYIDX9]], align 4 2827; CGSCC-NEXT: [[IDXPROM10:%.*]] = sext i32 [[IDX]] to i64 2828; CGSCC-NEXT: [[ARRAYIDX11:%.*]] = getelementptr inbounds [128 x i32], ptr [[BUF]], i64 0, i64 [[IDXPROM10]] 2829; CGSCC-NEXT: [[TMP2:%.*]] = load i32, ptr [[ARRAYIDX11]], align 4 2830; CGSCC-NEXT: [[CMP12:%.*]] = icmp sle i32 [[TMP1]], [[TMP2]] 2831; CGSCC-NEXT: [[CONV:%.*]] = zext i1 [[CMP12]] to i32 2832; CGSCC-NEXT: [[ARRAYIDX14:%.*]] = getelementptr inbounds i32, ptr [[OUT]], i64 [[IDXPROM8]] 2833; CGSCC-NEXT: store i32 [[CONV]], ptr [[ARRAYIDX14]], align 4 2834; CGSCC-NEXT: [[INC16]] = add nsw i32 [[I3_0]], 1 2835; CGSCC-NEXT: br label [[FOR_COND4]], !llvm.loop [[TBAA12]] 2836; 2837entry: 2838 %buf = alloca [128 x i32], align 16 2839 call void @llvm.lifetime.start.p0(i64 512, ptr %buf) #2 2840 br label %for.cond 2841 2842for.cond: ; preds = %for.body, %entry 2843 %i.0 = phi i32 [ 0, %entry ], [ %inc, %for.body ] 2844 %cmp = icmp slt i32 %i.0, 128 2845 br i1 %cmp, label %for.body, label %for.cond.cleanup 2846 2847for.cond.cleanup: ; preds = %for.cond 2848 br label %for.cond4 2849 2850for.body: ; preds = %for.cond 2851 %idxprom = sext i32 %i.0 to i64 2852 %arrayidx = getelementptr inbounds i32, ptr %in, i64 %idxprom 2853 %0 = load i32, ptr %arrayidx, align 4 2854 %arrayidx2 = getelementptr inbounds [128 x i32], ptr %buf, i64 0, i64 %idxprom 2855 store i32 %0, ptr %arrayidx2, align 4 2856 %inc = add nsw i32 %i.0, 1 2857 br label %for.cond, !llvm.loop !10 2858 2859for.cond4: ; preds = %for.body7, %for.cond.cleanup 2860 %i3.0 = phi i32 [ 0, %for.cond.cleanup ], [ %inc16, %for.body7 ] 2861 %cmp5 = icmp slt i32 %i3.0, 128 2862 br i1 %cmp5, label %for.body7, label %for.cond.cleanup6 2863 2864for.cond.cleanup6: ; preds = %for.cond4 2865 call void @llvm.lifetime.end.p0(i64 512, ptr %buf) #2 2866 ret void 2867 2868for.body7: ; preds = %for.cond4 2869 %idxprom8 = sext i32 %i3.0 to i64 2870 %arrayidx9 = getelementptr inbounds [128 x i32], ptr %buf, i64 0, i64 %idxprom8 2871 %1 = load i32, ptr %arrayidx9, align 4 2872 %idxprom10 = sext i32 %idx to i64 2873 %arrayidx11 = getelementptr inbounds [128 x i32], ptr %buf, i64 0, i64 %idxprom10 2874 %2 = load i32, ptr %arrayidx11, align 4 2875 %cmp12 = icmp sle i32 %1, %2 2876 %conv = zext i1 %cmp12 to i32 2877 %arrayidx14 = getelementptr inbounds i32, ptr %out, i64 %idxprom8 2878 store i32 %conv, ptr %arrayidx14, align 4 2879 %inc16 = add nsw i32 %i3.0, 1 2880 br label %for.cond4, !llvm.loop !12 2881} 2882 2883; Ensure we do not return true. 2884define internal i1 @alloca_non_unique(ptr %p, i32 %in, i1 %c) { 2885; TUNIT: Function Attrs: nofree nosync nounwind memory(argmem: readwrite) 2886; TUNIT-LABEL: define {{[^@]+}}@alloca_non_unique 2887; TUNIT-SAME: (ptr noalias nofree readonly align 4 captures(none) [[P:%.*]], i32 [[IN:%.*]], i1 noundef [[C:%.*]]) #[[ATTR12:[0-9]+]] { 2888; TUNIT-NEXT: [[A:%.*]] = alloca i32, align 4 2889; TUNIT-NEXT: store i32 [[IN]], ptr [[A]], align 4 2890; TUNIT-NEXT: br i1 [[C]], label [[T:%.*]], label [[F:%.*]] 2891; TUNIT: t: 2892; TUNIT-NEXT: [[R:%.*]] = call i1 @alloca_non_unique(ptr noalias nofree noundef nonnull readonly align 4 captures(none) dereferenceable(4) [[A]], i32 noundef 42, i1 noundef false) #[[ATTR14:[0-9]+]] 2893; TUNIT-NEXT: ret i1 [[R]] 2894; TUNIT: f: 2895; TUNIT-NEXT: [[L:%.*]] = load i32, ptr [[P]], align 4 2896; TUNIT-NEXT: [[CMP:%.*]] = icmp eq i32 [[IN]], [[L]] 2897; TUNIT-NEXT: ret i1 [[CMP]] 2898; 2899; CGSCC: Function Attrs: nofree nosync nounwind memory(argmem: readwrite) 2900; CGSCC-LABEL: define {{[^@]+}}@alloca_non_unique 2901; CGSCC-SAME: (ptr noalias nofree readonly align 4 captures(none) [[P:%.*]], i32 [[IN:%.*]], i1 noundef [[C:%.*]]) #[[ATTR14:[0-9]+]] { 2902; CGSCC-NEXT: [[A:%.*]] = alloca i32, align 4 2903; CGSCC-NEXT: store i32 [[IN]], ptr [[A]], align 4 2904; CGSCC-NEXT: br i1 [[C]], label [[T:%.*]], label [[F:%.*]] 2905; CGSCC: t: 2906; CGSCC-NEXT: [[R:%.*]] = call i1 @alloca_non_unique(ptr noalias nofree noundef nonnull readonly align 4 captures(none) dereferenceable(4) [[A]], i32 noundef 42, i1 noundef false) #[[ATTR17:[0-9]+]] 2907; CGSCC-NEXT: ret i1 [[R]] 2908; CGSCC: f: 2909; CGSCC-NEXT: [[L:%.*]] = load i32, ptr [[P]], align 4 2910; CGSCC-NEXT: [[CMP:%.*]] = icmp eq i32 [[IN]], [[L]] 2911; CGSCC-NEXT: ret i1 [[CMP]] 2912; 2913 %a = alloca i32 2914 store i32 %in, ptr %a 2915 br i1 %c, label %t, label %f 2916t: 2917 %r = call i1 @alloca_non_unique(ptr %a, i32 42, i1 false) 2918 ret i1 %r 2919f: 2920 %l = load i32, ptr %p 2921 %cmp = icmp eq i32 %in, %l 2922 ret i1 %cmp 2923} 2924 2925; Ensure we do not return true. 2926define i1 @alloca_non_unique_caller(i32 %in, i1 %c) { 2927; TUNIT: Function Attrs: nofree norecurse nosync nounwind memory(none) 2928; TUNIT-LABEL: define {{[^@]+}}@alloca_non_unique_caller 2929; TUNIT-SAME: (i32 [[IN:%.*]], i1 [[C:%.*]]) #[[ATTR13:[0-9]+]] { 2930; TUNIT-NEXT: [[R:%.*]] = call i1 @alloca_non_unique(ptr undef, i32 [[IN]], i1 noundef [[C]]) #[[ATTR14]] 2931; TUNIT-NEXT: ret i1 [[R]] 2932; 2933; CGSCC: Function Attrs: nofree nosync nounwind memory(none) 2934; CGSCC-LABEL: define {{[^@]+}}@alloca_non_unique_caller 2935; CGSCC-SAME: (i32 [[IN:%.*]], i1 noundef [[C:%.*]]) #[[ATTR15:[0-9]+]] { 2936; CGSCC-NEXT: [[R:%.*]] = call i1 @alloca_non_unique(ptr nofree undef, i32 [[IN]], i1 noundef [[C]]) #[[ATTR25:[0-9]+]] 2937; CGSCC-NEXT: ret i1 [[R]] 2938; 2939 %r = call i1 @alloca_non_unique(ptr undef, i32 %in, i1 %c) 2940 ret i1 %r 2941} 2942 2943; Ensure we do not return %bad or %l, but %sel 2944define i32 @scope_value_traversal(i32 %bad, i1 %c, i1 %c2) { 2945; TUNIT: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none) 2946; TUNIT-LABEL: define {{[^@]+}}@scope_value_traversal 2947; TUNIT-SAME: (i32 [[BAD:%.*]], i1 [[C:%.*]], i1 [[C2:%.*]]) #[[ATTR4]] { 2948; TUNIT-NEXT: [[A:%.*]] = alloca i32, align 4 2949; TUNIT-NEXT: store i32 [[BAD]], ptr [[A]], align 4 2950; TUNIT-NEXT: call void @scope_value_traversal_helper(ptr noalias nofree noundef nonnull align 4 captures(none) dereferenceable(4) [[A]], i1 [[C2]]) #[[ATTR22:[0-9]+]] 2951; TUNIT-NEXT: [[L:%.*]] = load i32, ptr [[A]], align 4 2952; TUNIT-NEXT: [[SEL:%.*]] = select i1 [[C]], i32 [[BAD]], i32 [[L]] 2953; TUNIT-NEXT: ret i32 [[SEL]] 2954; 2955; CGSCC: Function Attrs: mustprogress nofree nosync nounwind willreturn memory(none) 2956; CGSCC-LABEL: define {{[^@]+}}@scope_value_traversal 2957; CGSCC-SAME: (i32 [[BAD:%.*]], i1 [[C:%.*]], i1 [[C2:%.*]]) #[[ATTR16:[0-9]+]] { 2958; CGSCC-NEXT: [[A:%.*]] = alloca i32, align 4 2959; CGSCC-NEXT: store i32 [[BAD]], ptr [[A]], align 4 2960; CGSCC-NEXT: call void @scope_value_traversal_helper(ptr noalias nofree noundef nonnull align 4 captures(none) dereferenceable(4) [[A]], i1 [[C2]]) #[[ATTR26:[0-9]+]] 2961; CGSCC-NEXT: [[L:%.*]] = load i32, ptr [[A]], align 4 2962; CGSCC-NEXT: [[SEL:%.*]] = select i1 [[C]], i32 [[BAD]], i32 [[L]] 2963; CGSCC-NEXT: ret i32 [[SEL]] 2964; 2965 %a = alloca i32 2966 store i32 %bad, ptr %a 2967 call void @scope_value_traversal_helper(ptr %a, i1 %c2) 2968 %l = load i32, ptr %a 2969 %sel = select i1 %c, i32 %bad, i32 %l 2970 ret i32 %sel 2971} 2972 2973define void @scope_value_traversal_helper(ptr %a, i1 %c) { 2974; TUNIT: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(argmem: readwrite) 2975; TUNIT-LABEL: define {{[^@]+}}@scope_value_traversal_helper 2976; TUNIT-SAME: (ptr nofree noundef nonnull align 4 captures(none) dereferenceable(4) [[A:%.*]], i1 [[C:%.*]]) #[[ATTR1]] { 2977; TUNIT-NEXT: [[L:%.*]] = load i32, ptr [[A]], align 4 2978; TUNIT-NEXT: [[SEL:%.*]] = select i1 [[C]], i32 [[L]], i32 42 2979; TUNIT-NEXT: store i32 [[SEL]], ptr [[A]], align 4 2980; TUNIT-NEXT: ret void 2981; 2982; CGSCC: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(argmem: readwrite) 2983; CGSCC-LABEL: define {{[^@]+}}@scope_value_traversal_helper 2984; CGSCC-SAME: (ptr nofree noundef nonnull align 4 captures(none) dereferenceable(4) [[A:%.*]], i1 [[C:%.*]]) #[[ATTR13]] { 2985; CGSCC-NEXT: [[L:%.*]] = load i32, ptr [[A]], align 4 2986; CGSCC-NEXT: [[SEL:%.*]] = select i1 [[C]], i32 [[L]], i32 42 2987; CGSCC-NEXT: store i32 [[SEL]], ptr [[A]], align 4 2988; CGSCC-NEXT: ret void 2989; 2990 %l = load i32, ptr %a 2991 %sel = select i1 %c, i32 %l, i32 42 2992 store i32 %sel, ptr %a 2993 ret void 2994} 2995 2996define i8 @gep_index_from_binary_operator(i1 %cnd1, i1 %cnd2) { 2997; CHECK: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none) 2998; CHECK-LABEL: define {{[^@]+}}@gep_index_from_binary_operator 2999; CHECK-SAME: (i1 [[CND1:%.*]], i1 [[CND2:%.*]]) #[[ATTR4]] { 3000; CHECK-NEXT: entry: 3001; CHECK-NEXT: [[BYTES:%.*]] = alloca [1024 x i8], align 16 3002; CHECK-NEXT: [[GEP_FIXED:%.*]] = getelementptr inbounds [1024 x i8], ptr [[BYTES]], i64 0, i64 12 3003; CHECK-NEXT: ret i8 100 3004; 3005entry: 3006 %Bytes = alloca [1024 x i8], align 16 3007 %offset = add i64 5, 7 3008 %gep.fixed = getelementptr inbounds [1024 x i8], ptr %Bytes, i64 0, i64 12 3009 %gep.sum = getelementptr inbounds [1024 x i8], ptr %Bytes, i64 0, i64 %offset 3010 store i8 100, ptr %gep.fixed, align 4 3011 %i = load i8, ptr %gep.sum, align 4 3012 ret i8 %i 3013} 3014 3015define i8 @gep_index_from_memory(i1 %cnd1, i1 %cnd2) { 3016; CHECK: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none) 3017; CHECK-LABEL: define {{[^@]+}}@gep_index_from_memory 3018; CHECK-SAME: (i1 [[CND1:%.*]], i1 [[CND2:%.*]]) #[[ATTR4]] { 3019; CHECK-NEXT: entry: 3020; CHECK-NEXT: [[BYTES:%.*]] = alloca [1024 x i8], align 16 3021; CHECK-NEXT: [[GEP_LOADED:%.*]] = getelementptr inbounds [1024 x i8], ptr [[BYTES]], i64 0, i64 12 3022; CHECK-NEXT: ret i8 100 3023; 3024entry: 3025 %Bytes = alloca [1024 x i8], align 16 3026 %addr = alloca i64, align 16 3027 store i64 12, ptr %addr, align 8 3028 %offset = load i64, ptr %addr, align 8 3029 %gep.fixed = getelementptr inbounds [1024 x i8], ptr %Bytes, i64 0, i64 12 3030 3031 %gep.loaded = getelementptr inbounds [1024 x i8], ptr %Bytes, i64 0, i64 %offset 3032 store i8 100, ptr %gep.loaded, align 4 3033 3034 %i = load i8, ptr %gep.fixed, align 4 3035 ret i8 %i 3036} 3037 3038@G = internal global i32 0, align 4 3039 3040; Ensure this is not flattened to return 3 3041define i32 @a(i1 %c) { 3042; TUNIT: Function Attrs: nofree nosync nounwind 3043; TUNIT-LABEL: define {{[^@]+}}@a 3044; TUNIT-SAME: (i1 noundef [[C:%.*]]) #[[ATTR14]] { 3045; TUNIT-NEXT: store i32 3, ptr @G, align 4 3046; TUNIT-NEXT: br i1 [[C]], label [[T:%.*]], label [[F:%.*]] 3047; TUNIT: t: 3048; TUNIT-NEXT: [[REC:%.*]] = call i32 @a(i1 noundef false) #[[ATTR14]] 3049; TUNIT-NEXT: br label [[F]] 3050; TUNIT: f: 3051; TUNIT-NEXT: [[R:%.*]] = load i32, ptr @G, align 4 3052; TUNIT-NEXT: store i32 5, ptr @G, align 4 3053; TUNIT-NEXT: ret i32 [[R]] 3054; 3055; CGSCC: Function Attrs: nofree nosync nounwind 3056; CGSCC-LABEL: define {{[^@]+}}@a 3057; CGSCC-SAME: (i1 noundef [[C:%.*]]) #[[ATTR17]] { 3058; CGSCC-NEXT: store i32 3, ptr @G, align 4 3059; CGSCC-NEXT: br i1 [[C]], label [[T:%.*]], label [[F:%.*]] 3060; CGSCC: t: 3061; CGSCC-NEXT: [[REC:%.*]] = call i32 @a(i1 noundef false) #[[ATTR17]] 3062; CGSCC-NEXT: br label [[F]] 3063; CGSCC: f: 3064; CGSCC-NEXT: [[R:%.*]] = load i32, ptr @G, align 4 3065; CGSCC-NEXT: store i32 5, ptr @G, align 4 3066; CGSCC-NEXT: ret i32 [[R]] 3067; 3068 store i32 3, ptr @G 3069 br i1 %c, label %t, label %f 3070 3071t: 3072 %rec = call i32 @a(i1 false) 3073 br label %f 3074 3075f: 3076 %r = load i32, ptr @G 3077 store i32 5, ptr @G 3078 ret i32 %r 3079} 3080 3081@GC = internal global i32 undef, align 4 3082define void @atomicrmw(ptr %p, i32 %i, i1 %cnd) { 3083; TUNIT: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn 3084; TUNIT-LABEL: define {{[^@]+}}@atomicrmw 3085; TUNIT-SAME: (ptr nofree [[P:%.*]], i32 [[I:%.*]], i1 noundef [[CND:%.*]]) #[[ATTR3]] { 3086; TUNIT-NEXT: br i1 [[CND]], label [[T:%.*]], label [[M:%.*]] 3087; TUNIT: t: 3088; TUNIT-NEXT: br label [[M]] 3089; TUNIT: m: 3090; TUNIT-NEXT: [[ARMW:%.*]] = atomicrmw add ptr @GC, i32 [[I]] monotonic, align 4 3091; TUNIT-NEXT: ret void 3092; 3093; CGSCC: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn 3094; CGSCC-LABEL: define {{[^@]+}}@atomicrmw 3095; CGSCC-SAME: (ptr nofree [[P:%.*]], i32 [[I:%.*]], i1 noundef [[CND:%.*]]) #[[ATTR5]] { 3096; CGSCC-NEXT: br i1 [[CND]], label [[T:%.*]], label [[M:%.*]] 3097; CGSCC: t: 3098; CGSCC-NEXT: br label [[M]] 3099; CGSCC: m: 3100; CGSCC-NEXT: [[ARMW:%.*]] = atomicrmw add ptr @GC, i32 [[I]] monotonic, align 4 3101; CGSCC-NEXT: ret void 3102; 3103 %alloca = alloca <2 x ptr> 3104 %gep1 = getelementptr ptr, ptr %alloca, i32 0 3105 %gep2 = getelementptr ptr, ptr %alloca, i32 1 3106 store <2 x ptr> <ptr @GC, ptr @GC>, ptr %alloca 3107 br i1 %cnd, label %t, label %m 3108t: 3109 store ptr null, ptr %gep2 3110 br label %m 3111m: 3112 %l1 = load ptr, ptr %gep1 3113 %l2 = load ptr, ptr %gep2 3114 %c1 = icmp eq ptr %l2, %p 3115 call void @llvm.assume(i1 %c1) 3116 %s = select i1 true, ptr %l1, ptr %l2 3117 %armw = atomicrmw add ptr %s, i32 %i monotonic 3118 ret void 3119} 3120 3121@GRS = internal thread_local global i32 undef 3122@GRS2 = global i32 undef 3123 3124define i32 @recSimplify(i32 %v, i1 %cond) { 3125; TUNIT: Function Attrs: nofree nosync nounwind 3126; TUNIT-LABEL: define {{[^@]+}}@recSimplify 3127; TUNIT-SAME: (i32 [[V:%.*]], i1 noundef [[COND:%.*]]) #[[ATTR14]] { 3128; TUNIT-NEXT: br i1 [[COND]], label [[REC:%.*]], label [[COMP:%.*]] 3129; TUNIT: rec: 3130; TUNIT-NEXT: [[RV:%.*]] = call i32 @recSimplify(i32 undef, i1 noundef false) #[[ATTR14]] 3131; TUNIT-NEXT: ret i32 1 3132; TUNIT: comp: 3133; TUNIT-NEXT: store i32 1, ptr @GRS2, align 4 3134; TUNIT-NEXT: ret i32 1 3135; 3136; CGSCC: Function Attrs: nofree nosync nounwind 3137; CGSCC-LABEL: define {{[^@]+}}@recSimplify 3138; CGSCC-SAME: (i32 [[V:%.*]], i1 noundef [[COND:%.*]]) #[[ATTR17]] { 3139; CGSCC-NEXT: br i1 [[COND]], label [[REC:%.*]], label [[COMP:%.*]] 3140; CGSCC: rec: 3141; CGSCC-NEXT: [[RV:%.*]] = call i32 @recSimplify(i32 [[V]], i1 noundef false) #[[ATTR17]] 3142; CGSCC-NEXT: ret i32 [[RV]] 3143; CGSCC: comp: 3144; CGSCC-NEXT: store i32 [[V]], ptr @GRS, align 4 3145; CGSCC-NEXT: store i32 1, ptr @GRS2, align 4 3146; CGSCC-NEXT: [[L:%.*]] = load i32, ptr @GRS, align 4 3147; CGSCC-NEXT: [[C:%.*]] = icmp eq i32 [[L]], 1 3148; CGSCC-NEXT: call void @llvm.assume(i1 noundef [[C]]) #[[ATTR27:[0-9]+]] 3149; CGSCC-NEXT: [[R:%.*]] = call i32 @recSimplify2() #[[ATTR27]] 3150; CGSCC-NEXT: ret i32 [[R]] 3151; 3152 br i1 %cond, label %rec, label %comp 3153rec: 3154 %rv = call i32 @recSimplify(i32 %v, i1 false) 3155 ret i32 %rv 3156comp: 3157 store i32 %v, ptr @GRS 3158 %s1 = select i1 %cond, i32 1, i32 1 3159 %s2 = select i1 %cond, i32 1, i32 %s1 3160 store i32 %s2, ptr @GRS2 3161 %l = load i32, ptr @GRS 3162 %c = icmp eq i32 %l, %s2 3163 call void @llvm.assume(i1 %c) 3164 %r = call i32 @recSimplify2() 3165 ret i32 %r 3166} 3167 3168define internal i32 @recSimplify2() { 3169; CGSCC: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(read) 3170; CGSCC-LABEL: define {{[^@]+}}@recSimplify2 3171; CGSCC-SAME: () #[[ATTR7]] { 3172; CGSCC-NEXT: [[R:%.*]] = load i32, ptr @GRS, align 4 3173; CGSCC-NEXT: ret i32 [[R]] 3174; 3175 %r = load i32, ptr @GRS 3176 ret i32 %r 3177} 3178 3179; Verify we do not return 10. 3180define i32 @may_access_after_return(i32 noundef %N, i32 noundef %M) { 3181; TUNIT: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none) 3182; TUNIT-LABEL: define {{[^@]+}}@may_access_after_return 3183; TUNIT-SAME: (i32 noundef [[N:%.*]], i32 noundef [[M:%.*]]) #[[ATTR4]] { 3184; TUNIT-NEXT: entry: 3185; TUNIT-NEXT: [[A:%.*]] = alloca i32, align 4 3186; TUNIT-NEXT: [[B:%.*]] = alloca i32, align 4 3187; TUNIT-NEXT: call void @write_both(ptr nofree noundef nonnull writeonly align 4 captures(none) dereferenceable(4) [[A]], ptr nofree noundef nonnull writeonly align 4 captures(none) dereferenceable(4) [[B]]) #[[ATTR18]] 3188; TUNIT-NEXT: ret i32 8 3189; 3190; CGSCC: Function Attrs: mustprogress nofree nosync nounwind willreturn memory(none) 3191; CGSCC-LABEL: define {{[^@]+}}@may_access_after_return 3192; CGSCC-SAME: (i32 noundef [[N:%.*]], i32 noundef [[M:%.*]]) #[[ATTR16]] { 3193; CGSCC-NEXT: entry: 3194; CGSCC-NEXT: [[A:%.*]] = alloca i32, align 4 3195; CGSCC-NEXT: [[B:%.*]] = alloca i32, align 4 3196; CGSCC-NEXT: call void @write_both(ptr noalias nofree noundef nonnull writeonly align 4 captures(none) dereferenceable(4) [[A]], ptr noalias nofree noundef nonnull writeonly align 4 captures(none) dereferenceable(4) [[B]]) #[[ATTR21]] 3197; CGSCC-NEXT: [[TMP0:%.*]] = load i32, ptr [[A]], align 4 3198; CGSCC-NEXT: [[TMP1:%.*]] = load i32, ptr [[B]], align 4 3199; CGSCC-NEXT: [[ADD:%.*]] = add nsw i32 [[TMP0]], [[TMP1]] 3200; CGSCC-NEXT: ret i32 [[ADD]] 3201; 3202entry: 3203 %A = alloca i32, align 4 3204 %B = alloca i32, align 4 3205 %call = call ptr @passthrough(ptr noundef %A) 3206 %call1 = call ptr @passthrough(ptr noundef %B) 3207 call void @write_both(ptr noundef %call, ptr noundef %call1) 3208 %0 = load i32, ptr %A, align 4 3209 %1 = load i32, ptr %B, align 4 3210 %add = add nsw i32 %0, %1 3211 ret i32 %add 3212} 3213 3214define internal void @write_both(ptr noundef %Q, ptr noundef %R) { 3215; CHECK: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(argmem: write) 3216; CHECK-LABEL: define {{[^@]+}}@write_both 3217; CHECK-SAME: (ptr nofree noundef nonnull writeonly align 4 captures(none) dereferenceable(4) [[Q:%.*]], ptr nofree noundef nonnull writeonly align 4 captures(none) dereferenceable(4) [[R:%.*]]) #[[ATTR0]] { 3218; CHECK-NEXT: entry: 3219; CHECK-NEXT: store i32 3, ptr [[Q]], align 4 3220; CHECK-NEXT: store i32 5, ptr [[R]], align 4 3221; CHECK-NEXT: ret void 3222; 3223entry: 3224 store i32 3, ptr %Q, align 4 3225 store i32 5, ptr %R, align 4 3226 ret void 3227} 3228 3229define internal ptr @passthrough(ptr noundef %P) { 3230; CGSCC: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none) 3231; CGSCC-LABEL: define {{[^@]+}}@passthrough 3232; CGSCC-SAME: (ptr noalias nofree noundef nonnull readnone returned align 4 dereferenceable(4) "no-capture-maybe-returned" [[P:%.*]]) #[[ATTR4]] { 3233; CGSCC-NEXT: entry: 3234; CGSCC-NEXT: ret ptr [[P]] 3235; 3236entry: 3237 ret ptr %P 3238} 3239 3240; Verify we do not return 10. 3241define i32 @may_access_after_return_choice(i32 noundef %N, i32 noundef %M, i1 %c) { 3242; TUNIT: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none) 3243; TUNIT-LABEL: define {{[^@]+}}@may_access_after_return_choice 3244; TUNIT-SAME: (i32 noundef [[N:%.*]], i32 noundef [[M:%.*]], i1 [[C:%.*]]) #[[ATTR4]] { 3245; TUNIT-NEXT: entry: 3246; TUNIT-NEXT: [[A:%.*]] = alloca i32, align 4 3247; TUNIT-NEXT: [[B:%.*]] = alloca i32, align 4 3248; TUNIT-NEXT: [[CALL:%.*]] = call nonnull align 4 dereferenceable(4) ptr @passthrough_choice(i1 [[C]], ptr noalias nofree noundef nonnull readnone align 4 dereferenceable(4) "no-capture-maybe-returned" [[A]], ptr noalias nofree noundef nonnull readnone align 4 dereferenceable(4) "no-capture-maybe-returned" [[B]]) #[[ATTR23:[0-9]+]] 3249; TUNIT-NEXT: [[CALL1:%.*]] = call nonnull align 4 dereferenceable(4) ptr @passthrough_choice(i1 [[C]], ptr noalias nofree noundef nonnull readnone align 4 dereferenceable(4) "no-capture-maybe-returned" [[B]], ptr noalias nofree noundef nonnull readnone align 4 dereferenceable(4) "no-capture-maybe-returned" [[A]]) #[[ATTR23]] 3250; TUNIT-NEXT: call void @write_both(ptr nofree noundef nonnull writeonly align 4 captures(none) dereferenceable(4) [[CALL]], ptr nofree noundef nonnull writeonly align 4 captures(none) dereferenceable(4) [[CALL1]]) #[[ATTR18]] 3251; TUNIT-NEXT: [[TMP0:%.*]] = load i32, ptr [[A]], align 4 3252; TUNIT-NEXT: [[TMP1:%.*]] = load i32, ptr [[B]], align 4 3253; TUNIT-NEXT: [[ADD:%.*]] = add nsw i32 [[TMP0]], [[TMP1]] 3254; TUNIT-NEXT: ret i32 [[ADD]] 3255; 3256; CGSCC: Function Attrs: mustprogress nofree nosync nounwind willreturn 3257; CGSCC-LABEL: define {{[^@]+}}@may_access_after_return_choice 3258; CGSCC-SAME: (i32 noundef [[N:%.*]], i32 noundef [[M:%.*]], i1 [[C:%.*]]) #[[ATTR3]] { 3259; CGSCC-NEXT: entry: 3260; CGSCC-NEXT: [[A:%.*]] = alloca i32, align 4 3261; CGSCC-NEXT: [[B:%.*]] = alloca i32, align 4 3262; CGSCC-NEXT: [[CALL:%.*]] = call nonnull align 4 dereferenceable(4) ptr @passthrough_choice(i1 [[C]], ptr noalias nofree noundef nonnull readnone align 4 dereferenceable(4) [[A]], ptr noalias nofree noundef nonnull readnone align 4 dereferenceable(4) [[B]]) #[[ATTR28:[0-9]+]] 3263; CGSCC-NEXT: [[CALL1:%.*]] = call nonnull align 4 dereferenceable(4) ptr @passthrough_choice(i1 [[C]], ptr noalias nofree noundef nonnull readnone align 4 dereferenceable(4) [[B]], ptr noalias nofree noundef nonnull readnone align 4 dereferenceable(4) [[A]]) #[[ATTR28]] 3264; CGSCC-NEXT: call void @write_both(ptr nofree noundef nonnull writeonly align 4 captures(none) dereferenceable(4) [[CALL]], ptr nofree noundef nonnull writeonly align 4 captures(none) dereferenceable(4) [[CALL1]]) #[[ATTR21]] 3265; CGSCC-NEXT: [[TMP0:%.*]] = load i32, ptr [[A]], align 4 3266; CGSCC-NEXT: [[TMP1:%.*]] = load i32, ptr [[B]], align 4 3267; CGSCC-NEXT: [[ADD:%.*]] = add nsw i32 [[TMP0]], [[TMP1]] 3268; CGSCC-NEXT: ret i32 [[ADD]] 3269; 3270entry: 3271 %A = alloca i32, align 4 3272 %B = alloca i32, align 4 3273 %call = call ptr @passthrough_choice(i1 %c, ptr noundef %A, ptr noundef %B) 3274 %call1 = call ptr @passthrough_choice(i1 %c, ptr noundef %B, ptr noundef %A) 3275 call void @write_both(ptr noundef %call, ptr noundef %call1) 3276 %0 = load i32, ptr %A, align 4 3277 %1 = load i32, ptr %B, align 4 3278 %add = add nsw i32 %0, %1 3279 ret i32 %add 3280} 3281 3282define internal ptr @passthrough_choice(i1 %c, ptr noundef %P, ptr noundef %Q) { 3283; CHECK: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none) 3284; CHECK-LABEL: define {{[^@]+}}@passthrough_choice 3285; CHECK-SAME: (i1 [[C:%.*]], ptr noalias nofree noundef nonnull readnone align 4 dereferenceable(4) "no-capture-maybe-returned" [[P:%.*]], ptr noalias nofree noundef nonnull readnone align 4 dereferenceable(4) "no-capture-maybe-returned" [[Q:%.*]]) #[[ATTR4]] { 3286; CHECK-NEXT: entry: 3287; CHECK-NEXT: [[R:%.*]] = select i1 [[C]], ptr [[P]], ptr [[Q]] 3288; CHECK-NEXT: ret ptr [[R]] 3289; 3290entry: 3291 %R = select i1 %c, ptr %P, ptr %Q 3292 ret ptr %R 3293} 3294 3295; Verify we do not return 10. 3296define i32 @may_access_after_return_no_choice1(i32 noundef %N, i32 noundef %M) { 3297; TUNIT: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none) 3298; TUNIT-LABEL: define {{[^@]+}}@may_access_after_return_no_choice1 3299; TUNIT-SAME: (i32 noundef [[N:%.*]], i32 noundef [[M:%.*]]) #[[ATTR4]] { 3300; TUNIT-NEXT: entry: 3301; TUNIT-NEXT: [[A:%.*]] = alloca i32, align 4 3302; TUNIT-NEXT: [[B:%.*]] = alloca i32, align 4 3303; TUNIT-NEXT: call void @write_both(ptr nofree noundef nonnull writeonly align 4 captures(none) dereferenceable(4) [[A]], ptr nofree noundef nonnull writeonly align 4 captures(none) dereferenceable(4) [[B]]) #[[ATTR18]] 3304; TUNIT-NEXT: ret i32 8 3305; 3306; CGSCC: Function Attrs: mustprogress nofree nosync nounwind willreturn memory(none) 3307; CGSCC-LABEL: define {{[^@]+}}@may_access_after_return_no_choice1 3308; CGSCC-SAME: (i32 noundef [[N:%.*]], i32 noundef [[M:%.*]]) #[[ATTR16]] { 3309; CGSCC-NEXT: entry: 3310; CGSCC-NEXT: [[A:%.*]] = alloca i32, align 4 3311; CGSCC-NEXT: [[B:%.*]] = alloca i32, align 4 3312; CGSCC-NEXT: call void @write_both(ptr noalias nofree noundef nonnull writeonly align 4 captures(none) dereferenceable(4) [[A]], ptr noalias nofree noundef nonnull writeonly align 4 captures(none) dereferenceable(4) [[B]]) #[[ATTR21]] 3313; CGSCC-NEXT: [[TMP0:%.*]] = load i32, ptr [[A]], align 4 3314; CGSCC-NEXT: [[TMP1:%.*]] = load i32, ptr [[B]], align 4 3315; CGSCC-NEXT: [[ADD:%.*]] = add nsw i32 [[TMP0]], [[TMP1]] 3316; CGSCC-NEXT: ret i32 [[ADD]] 3317; 3318entry: 3319 %A = alloca i32, align 4 3320 %B = alloca i32, align 4 3321 %call = call ptr @passthrough_no_choice_true(i1 true, ptr noundef %A, ptr noundef %B) 3322 %call1 = call ptr @passthrough_no_choice_true(i1 true, ptr noundef %B, ptr noundef %A) 3323 call void @write_both(ptr noundef %call, ptr noundef %call1) 3324 %0 = load i32, ptr %A, align 4 3325 %1 = load i32, ptr %B, align 4 3326 %add = add nsw i32 %0, %1 3327 ret i32 %add 3328} 3329 3330; Verify we do not return 10. 3331define i32 @may_access_after_return_no_choice2(i32 noundef %N, i32 noundef %M) { 3332; TUNIT: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none) 3333; TUNIT-LABEL: define {{[^@]+}}@may_access_after_return_no_choice2 3334; TUNIT-SAME: (i32 noundef [[N:%.*]], i32 noundef [[M:%.*]]) #[[ATTR4]] { 3335; TUNIT-NEXT: entry: 3336; TUNIT-NEXT: [[A:%.*]] = alloca i32, align 4 3337; TUNIT-NEXT: [[B:%.*]] = alloca i32, align 4 3338; TUNIT-NEXT: call void @write_both(ptr nofree noundef nonnull writeonly align 4 captures(none) dereferenceable(4) [[B]], ptr nofree noundef nonnull writeonly align 4 captures(none) dereferenceable(4) [[A]]) #[[ATTR18]] 3339; TUNIT-NEXT: ret i32 8 3340; 3341; CGSCC: Function Attrs: mustprogress nofree nosync nounwind willreturn memory(none) 3342; CGSCC-LABEL: define {{[^@]+}}@may_access_after_return_no_choice2 3343; CGSCC-SAME: (i32 noundef [[N:%.*]], i32 noundef [[M:%.*]]) #[[ATTR16]] { 3344; CGSCC-NEXT: entry: 3345; CGSCC-NEXT: [[A:%.*]] = alloca i32, align 4 3346; CGSCC-NEXT: [[B:%.*]] = alloca i32, align 4 3347; CGSCC-NEXT: call void @write_both(ptr noalias nofree noundef nonnull writeonly align 4 captures(none) dereferenceable(4) [[B]], ptr noalias nofree noundef nonnull writeonly align 4 captures(none) dereferenceable(4) [[A]]) #[[ATTR21]] 3348; CGSCC-NEXT: [[TMP0:%.*]] = load i32, ptr [[A]], align 4 3349; CGSCC-NEXT: [[TMP1:%.*]] = load i32, ptr [[B]], align 4 3350; CGSCC-NEXT: [[ADD:%.*]] = add nsw i32 [[TMP0]], [[TMP1]] 3351; CGSCC-NEXT: ret i32 [[ADD]] 3352; 3353entry: 3354 %A = alloca i32, align 4 3355 %B = alloca i32, align 4 3356 %call = call ptr @passthrough_no_choice_false(i1 false, ptr noundef %A, ptr noundef %B) 3357 %call1 = call ptr @passthrough_no_choice_false(i1 false, ptr noundef %B, ptr noundef %A) 3358 call void @write_both(ptr noundef %call, ptr noundef %call1) 3359 %0 = load i32, ptr %A, align 4 3360 %1 = load i32, ptr %B, align 4 3361 %add = add nsw i32 %0, %1 3362 ret i32 %add 3363} 3364 3365define internal ptr @passthrough_no_choice_true(i1 %c, ptr noundef %P, ptr noundef %Q) { 3366; CGSCC: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none) 3367; CGSCC-LABEL: define {{[^@]+}}@passthrough_no_choice_true 3368; CGSCC-SAME: (ptr noalias nofree noundef nonnull readnone returned align 4 dereferenceable(4) "no-capture-maybe-returned" [[P:%.*]], i32 [[TMP0:%.*]]) #[[ATTR4]] { 3369; CGSCC-NEXT: entry: 3370; CGSCC-NEXT: [[Q_PRIV:%.*]] = alloca i32, align 4 3371; CGSCC-NEXT: store i32 [[TMP0]], ptr [[Q_PRIV]], align 4 3372; CGSCC-NEXT: ret ptr [[P]] 3373; 3374entry: 3375 %R = select i1 %c, ptr %P, ptr %Q 3376 ret ptr %R 3377} 3378define internal ptr @passthrough_no_choice_false(i1 %c, ptr noundef %P, ptr noundef %Q) { 3379; CGSCC: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none) 3380; CGSCC-LABEL: define {{[^@]+}}@passthrough_no_choice_false 3381; CGSCC-SAME: (i32 [[TMP0:%.*]], ptr noalias nofree noundef nonnull readnone returned align 4 dereferenceable(4) "no-capture-maybe-returned" [[Q:%.*]]) #[[ATTR4]] { 3382; CGSCC-NEXT: entry: 3383; CGSCC-NEXT: [[P_PRIV:%.*]] = alloca i32, align 4 3384; CGSCC-NEXT: store i32 [[TMP0]], ptr [[P_PRIV]], align 4 3385; CGSCC-NEXT: ret ptr [[Q]] 3386; 3387entry: 3388 %R = select i1 %c, ptr %P, ptr %Q 3389 ret ptr %R 3390} 3391 3392define ptr @move2(ptr %p) { 3393; CHECK: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none) 3394; CHECK-LABEL: define {{[^@]+}}@move2 3395; CHECK-SAME: (ptr nofree readnone "no-capture-maybe-returned" [[P:%.*]]) #[[ATTR4]] { 3396; CHECK-NEXT: [[G:%.*]] = getelementptr i8, ptr [[P]], i32 2 3397; CHECK-NEXT: ret ptr [[G]] 3398; 3399 %g = getelementptr i8, ptr %p, i32 2 3400 ret ptr %g 3401} 3402define internal ptr @move4(ptr %p) { 3403; CHECK: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none) 3404; CHECK-LABEL: define {{[^@]+}}@move4 3405; CHECK-SAME: (ptr noalias nofree readnone "no-capture-maybe-returned" [[P:%.*]]) #[[ATTR4]] { 3406; CHECK-NEXT: [[G:%.*]] = getelementptr i8, ptr [[P]], i32 4 3407; CHECK-NEXT: ret ptr [[G]] 3408; 3409 %g = getelementptr i8, ptr %p, i32 4 3410 ret ptr %g 3411} 3412 3413define ptr @move246(i32 %i, ptr %p) { 3414; CHECK: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none) 3415; CHECK-LABEL: define {{[^@]+}}@move246 3416; CHECK-SAME: (i32 [[I:%.*]], ptr nofree readnone "no-capture-maybe-returned" [[P:%.*]]) #[[ATTR4]] { 3417; CHECK-NEXT: [[C0:%.*]] = icmp eq i32 [[I]], 0 3418; CHECK-NEXT: br i1 [[C0]], label [[BG2:%.*]], label [[BG46:%.*]] 3419; CHECK: bg2: 3420; CHECK-NEXT: [[G2:%.*]] = getelementptr i8, ptr [[P]], i32 2 3421; CHECK-NEXT: ret ptr [[G2]] 3422; CHECK: bg46: 3423; CHECK-NEXT: [[C1:%.*]] = icmp eq i32 [[I]], 1 3424; CHECK-NEXT: br i1 [[C1]], label [[BG4:%.*]], label [[BG6:%.*]] 3425; CHECK: bg4: 3426; CHECK-NEXT: [[G4:%.*]] = getelementptr i8, ptr [[P]], i32 4 3427; CHECK-NEXT: ret ptr [[G4]] 3428; CHECK: bg6: 3429; CHECK-NEXT: [[G6:%.*]] = getelementptr i8, ptr [[P]], i32 6 3430; CHECK-NEXT: ret ptr [[G6]] 3431; 3432 %c0 = icmp eq i32 %i, 0 3433 br i1 %c0, label %bg2, label %bg46 3434bg2: 3435 %g2 = getelementptr i8, ptr %p, i32 2 3436 ret ptr %g2 3437bg46: 3438 %c1 = icmp eq i32 %i, 1 3439 br i1 %c1, label %bg4, label %bg6 3440bg4: 3441 %g4 = getelementptr i8, ptr %p, i32 4 3442 ret ptr %g4 3443bg6: 3444 %g6 = getelementptr i8, ptr %p, i32 6 3445 ret ptr %g6 3446} 3447 3448declare void @use3i8(i8, i8, i8) 3449 3450define void @returnedPtrAccesses() { 3451; TUNIT-LABEL: define {{[^@]+}}@returnedPtrAccesses() { 3452; TUNIT-NEXT: [[A:%.*]] = alloca i64, align 8 3453; TUNIT-NEXT: [[A2:%.*]] = call ptr @move2(ptr noalias nofree noundef nonnull readnone align 8 dereferenceable(8) "no-capture-maybe-returned" [[A]]) #[[ATTR23]] 3454; TUNIT-NEXT: [[A4:%.*]] = call ptr @move4(ptr noalias nofree noundef nonnull readnone align 8 dereferenceable(8) "no-capture-maybe-returned" [[A]]) #[[ATTR23]] 3455; TUNIT-NEXT: [[A6:%.*]] = call ptr @move4(ptr noalias nofree readnone "no-capture-maybe-returned" [[A2]]) #[[ATTR23]] 3456; TUNIT-NEXT: store i8 2, ptr [[A2]], align 1 3457; TUNIT-NEXT: store i8 4, ptr [[A4]], align 1 3458; TUNIT-NEXT: store i8 6, ptr [[A6]], align 1 3459; TUNIT-NEXT: call void @use3i8(i8 2, i8 4, i8 6) 3460; TUNIT-NEXT: ret void 3461; 3462; CGSCC-LABEL: define {{[^@]+}}@returnedPtrAccesses() { 3463; CGSCC-NEXT: [[A:%.*]] = alloca i64, align 8 3464; CGSCC-NEXT: [[A2:%.*]] = call nonnull dereferenceable(1) ptr @move2(ptr noalias nofree noundef nonnull readnone align 8 dereferenceable(8) [[A]]) #[[ATTR20]] 3465; CGSCC-NEXT: [[A4:%.*]] = call ptr @move4(ptr noalias nofree noundef nonnull readnone align 8 dereferenceable(8) [[A]]) #[[ATTR20]] 3466; CGSCC-NEXT: [[A6:%.*]] = call ptr @move4(ptr noalias nofree noundef nonnull readnone dereferenceable(1) [[A2]]) #[[ATTR20]] 3467; CGSCC-NEXT: [[G2:%.*]] = getelementptr i8, ptr [[A]], i32 2 3468; CGSCC-NEXT: [[G4:%.*]] = getelementptr i8, ptr [[A]], i32 4 3469; CGSCC-NEXT: [[G6:%.*]] = getelementptr i8, ptr [[A]], i32 6 3470; CGSCC-NEXT: store i8 2, ptr [[A2]], align 1 3471; CGSCC-NEXT: store i8 4, ptr [[A4]], align 1 3472; CGSCC-NEXT: store i8 6, ptr [[A6]], align 1 3473; CGSCC-NEXT: [[L2:%.*]] = load i8, ptr [[G2]], align 2 3474; CGSCC-NEXT: [[L4:%.*]] = load i8, ptr [[G4]], align 4 3475; CGSCC-NEXT: [[L6:%.*]] = load i8, ptr [[G6]], align 2 3476; CGSCC-NEXT: call void @use3i8(i8 [[L2]], i8 [[L4]], i8 [[L6]]) 3477; CGSCC-NEXT: ret void 3478; 3479 %a = alloca i64 3480 %a2 = call ptr @move2(ptr %a) 3481 %a4 = call ptr @move4(ptr %a) 3482 %a6 = call ptr @move4(ptr %a2) 3483 %g2 = getelementptr i8, ptr %a, i32 2 3484 %g4 = getelementptr i8, ptr %a, i32 4 3485 %g6 = getelementptr i8, ptr %a, i32 6 3486 store i8 2, ptr %a2 3487 store i8 4, ptr %a4 3488 store i8 6, ptr %a6 3489 %l2 = load i8, ptr %g2 3490 %l4 = load i8, ptr %g4 3491 %l6 = load i8, ptr %g6 3492 call void @use3i8(i8 %l2, i8 %l4, i8 %l6) 3493 ret void 3494} 3495 3496define void @returnedPtrAccessesMultiple(i32 %i) { 3497; TUNIT-LABEL: define {{[^@]+}}@returnedPtrAccessesMultiple 3498; TUNIT-SAME: (i32 [[I:%.*]]) { 3499; TUNIT-NEXT: [[A:%.*]] = alloca i64, align 8 3500; TUNIT-NEXT: [[AP:%.*]] = call ptr @move246(i32 [[I]], ptr noalias nofree noundef nonnull readnone align 8 dereferenceable(8) "no-capture-maybe-returned" [[A]]) #[[ATTR23]] 3501; TUNIT-NEXT: store i8 2, ptr [[AP]], align 1 3502; TUNIT-NEXT: call void @use3i8(i8 2, i8 2, i8 2) 3503; TUNIT-NEXT: ret void 3504; 3505; CGSCC-LABEL: define {{[^@]+}}@returnedPtrAccessesMultiple 3506; CGSCC-SAME: (i32 [[I:%.*]]) { 3507; CGSCC-NEXT: [[A:%.*]] = alloca i64, align 8 3508; CGSCC-NEXT: [[AP:%.*]] = call ptr @move246(i32 [[I]], ptr noalias nofree noundef nonnull readnone align 8 dereferenceable(8) [[A]]) #[[ATTR20]] 3509; CGSCC-NEXT: [[G2:%.*]] = getelementptr i8, ptr [[A]], i32 2 3510; CGSCC-NEXT: [[G4:%.*]] = getelementptr i8, ptr [[A]], i32 4 3511; CGSCC-NEXT: [[G6:%.*]] = getelementptr i8, ptr [[A]], i32 6 3512; CGSCC-NEXT: store i8 2, ptr [[AP]], align 1 3513; CGSCC-NEXT: [[L2:%.*]] = load i8, ptr [[G2]], align 2 3514; CGSCC-NEXT: [[L4:%.*]] = load i8, ptr [[G4]], align 4 3515; CGSCC-NEXT: [[L6:%.*]] = load i8, ptr [[G6]], align 2 3516; CGSCC-NEXT: call void @use3i8(i8 [[L2]], i8 [[L4]], i8 [[L6]]) 3517; CGSCC-NEXT: ret void 3518; 3519 %a = alloca i64 3520 %ap = call ptr @move246(i32 %i, ptr %a) 3521 %g2 = getelementptr i8, ptr %a, i32 2 3522 %g4 = getelementptr i8, ptr %a, i32 4 3523 %g6 = getelementptr i8, ptr %a, i32 6 3524 store i8 2, ptr %ap 3525 %l2 = load i8, ptr %g2 3526 %l4 = load i8, ptr %g4 3527 %l6 = load i8, ptr %g6 3528 call void @use3i8(i8 %l2, i8 %l4, i8 %l6) 3529 ret void 3530} 3531 3532define void @returnedPtrAccessesMultiple2(i32 %i) { 3533; TUNIT-LABEL: define {{[^@]+}}@returnedPtrAccessesMultiple2 3534; TUNIT-SAME: (i32 [[I:%.*]]) { 3535; TUNIT-NEXT: [[A:%.*]] = alloca i64, align 8 3536; TUNIT-NEXT: [[G2:%.*]] = getelementptr i8, ptr [[A]], i32 2 3537; TUNIT-NEXT: [[G4:%.*]] = getelementptr i8, ptr [[A]], i32 4 3538; TUNIT-NEXT: [[G6:%.*]] = getelementptr i8, ptr [[A]], i32 6 3539; TUNIT-NEXT: store i8 0, ptr [[G2]], align 2 3540; TUNIT-NEXT: store i8 0, ptr [[G4]], align 4 3541; TUNIT-NEXT: store i8 0, ptr [[G6]], align 2 3542; TUNIT-NEXT: [[AP:%.*]] = call ptr @move246(i32 [[I]], ptr noalias nofree noundef nonnull readnone align 8 dereferenceable(8) "no-capture-maybe-returned" [[A]]) #[[ATTR23]] 3543; TUNIT-NEXT: store i8 2, ptr [[AP]], align 1 3544; TUNIT-NEXT: [[L2:%.*]] = load i8, ptr [[G2]], align 2 3545; TUNIT-NEXT: [[L4:%.*]] = load i8, ptr [[G4]], align 4 3546; TUNIT-NEXT: [[L6:%.*]] = load i8, ptr [[G6]], align 2 3547; TUNIT-NEXT: call void @use3i8(i8 noundef [[L2]], i8 noundef [[L4]], i8 noundef [[L6]]) 3548; TUNIT-NEXT: ret void 3549; 3550; CGSCC-LABEL: define {{[^@]+}}@returnedPtrAccessesMultiple2 3551; CGSCC-SAME: (i32 [[I:%.*]]) { 3552; CGSCC-NEXT: [[A:%.*]] = alloca i64, align 8 3553; CGSCC-NEXT: [[G2:%.*]] = getelementptr i8, ptr [[A]], i32 2 3554; CGSCC-NEXT: [[G4:%.*]] = getelementptr i8, ptr [[A]], i32 4 3555; CGSCC-NEXT: [[G6:%.*]] = getelementptr i8, ptr [[A]], i32 6 3556; CGSCC-NEXT: store i8 0, ptr [[G2]], align 2 3557; CGSCC-NEXT: store i8 0, ptr [[G4]], align 4 3558; CGSCC-NEXT: store i8 0, ptr [[G6]], align 2 3559; CGSCC-NEXT: [[AP:%.*]] = call ptr @move246(i32 [[I]], ptr noalias nofree noundef nonnull readnone align 8 dereferenceable(8) [[A]]) #[[ATTR20]] 3560; CGSCC-NEXT: store i8 2, ptr [[AP]], align 1 3561; CGSCC-NEXT: [[L2:%.*]] = load i8, ptr [[G2]], align 2 3562; CGSCC-NEXT: [[L4:%.*]] = load i8, ptr [[G4]], align 4 3563; CGSCC-NEXT: [[L6:%.*]] = load i8, ptr [[G6]], align 2 3564; CGSCC-NEXT: call void @use3i8(i8 [[L2]], i8 [[L4]], i8 [[L6]]) 3565; CGSCC-NEXT: ret void 3566; 3567 %a = alloca i64 3568 %g2 = getelementptr i8, ptr %a, i32 2 3569 %g4 = getelementptr i8, ptr %a, i32 4 3570 %g6 = getelementptr i8, ptr %a, i32 6 3571 store i8 0, ptr %g2 3572 store i8 0, ptr %g4 3573 store i8 0, ptr %g6 3574 %ap = call ptr @move246(i32 %i, ptr %a) 3575 store i8 2, ptr %ap 3576 %l2 = load i8, ptr %g2 3577 %l4 = load i8, ptr %g4 3578 %l6 = load i8, ptr %g6 3579 call void @use3i8(i8 %l2, i8 %l4, i8 %l6) 3580 ret void 3581} 3582 3583declare void @llvm.assume(i1 noundef) 3584 3585 3586!llvm.module.flags = !{!0, !1} 3587!llvm.ident = !{!2} 3588 3589!0 = !{i32 1, !"wchar_size", i32 4} 3590!1 = !{i32 7, !"uwtable", i32 1} 3591!2 = !{!"clang version 13.0.0"} 3592!3 = !{!4, !4, i64 0} 3593!4 = !{!"int", !5, i64 0} 3594!5 = !{!"omnipotent char", !6, i64 0} 3595!6 = !{!"Simple C/C++ TBAA"} 3596!7 = !{!8, !9, i64 12} 3597!8 = !{!"S", !4, i64 0, !4, i64 4, !4, i64 8, !9, i64 12, !9, i64 16, !9, i64 20} 3598!9 = !{!"float", !5, i64 0} 3599!10 = !{!8, !9, i64 16} 3600!11 = !{!8, !9, i64 20} 3601!12 = !{!8, !4, i64 0} 3602!13 = !{!8, !4, i64 4} 3603!14 = !{!8, !4, i64 8} 3604!15 = !{!5, !5, i64 0} 3605!16 = distinct !{!16, !17} 3606!17 = !{!"llvm.loop.mustprogress"} 3607!18 = !{!9, !9, i64 0} 3608!19 = distinct !{!19, !17} 3609!20 = !{!21, !21, i64 0} 3610!21 = !{!"long long", !5, i64 0} 3611!22 = distinct !{!22, !17} 3612!23 = distinct !{!23, !17} 3613!24 = distinct !{!24, !17} 3614!25 = distinct !{!25, !17} 3615!26 = distinct !{!26, !17} 3616!27 = distinct !{!27, !17} 3617!28 = distinct !{!28, !17} 3618!29 = distinct !{!29, !17} 3619!30 = distinct !{!30, !17} 3620!31 = distinct !{!31, !17} 3621;. 3622; TUNIT: attributes #[[ATTR0]] = { mustprogress nofree norecurse nosync nounwind willreturn memory(argmem: write) } 3623; TUNIT: attributes #[[ATTR1]] = { mustprogress nofree norecurse nosync nounwind willreturn memory(argmem: readwrite) } 3624; TUNIT: attributes #[[ATTR2:[0-9]+]] = { nocallback nofree nosync nounwind willreturn memory(argmem: readwrite) } 3625; TUNIT: attributes #[[ATTR3]] = { mustprogress nofree norecurse nosync nounwind willreturn } 3626; TUNIT: attributes #[[ATTR4]] = { mustprogress nofree norecurse nosync nounwind willreturn memory(none) } 3627; TUNIT: attributes #[[ATTR5]] = { mustprogress nofree norecurse nosync nounwind willreturn memory(write) } 3628; TUNIT: attributes #[[ATTR6]] = { mustprogress nofree norecurse nosync nounwind willreturn memory(read) } 3629; TUNIT: attributes #[[ATTR7]] = { nofree norecurse nosync nounwind memory(write) } 3630; TUNIT: attributes #[[ATTR8:[0-9]+]] = { allockind("alloc,uninitialized") allocsize(0) "alloc-family"="malloc" } 3631; TUNIT: attributes #[[ATTR9:[0-9]+]] = { allockind("free") "alloc-family"="malloc" } 3632; TUNIT: attributes #[[ATTR10:[0-9]+]] = { allockind("alloc,zeroed") allocsize(0,1) "alloc-family"="malloc" } 3633; TUNIT: attributes #[[ATTR11]] = { mustprogress nofree norecurse nosync nounwind willreturn uwtable } 3634; TUNIT: attributes #[[ATTR12]] = { nofree nosync nounwind memory(argmem: readwrite) } 3635; TUNIT: attributes #[[ATTR13]] = { nofree norecurse nosync nounwind memory(none) } 3636; TUNIT: attributes #[[ATTR14]] = { nofree nosync nounwind } 3637; TUNIT: attributes #[[ATTR15:[0-9]+]] = { nocallback nofree nosync nounwind willreturn memory(inaccessiblemem: write) } 3638; TUNIT: attributes #[[ATTR16:[0-9]+]] = { nocallback nofree nounwind willreturn memory(argmem: write) } 3639; TUNIT: attributes #[[ATTR17]] = { nofree willreturn } 3640; TUNIT: attributes #[[ATTR18]] = { nofree nosync nounwind willreturn memory(write) } 3641; TUNIT: attributes #[[ATTR19]] = { nocallback } 3642; TUNIT: attributes #[[ATTR20]] = { norecurse } 3643; TUNIT: attributes #[[ATTR21]] = { nounwind } 3644; TUNIT: attributes #[[ATTR22]] = { nofree nosync nounwind willreturn } 3645; TUNIT: attributes #[[ATTR23]] = { nofree nosync nounwind willreturn memory(none) } 3646;. 3647; CGSCC: attributes #[[ATTR0]] = { mustprogress nofree norecurse nosync nounwind willreturn memory(argmem: write) } 3648; CGSCC: attributes #[[ATTR1]] = { mustprogress nofree nosync nounwind willreturn memory(argmem: readwrite) } 3649; CGSCC: attributes #[[ATTR2:[0-9]+]] = { nocallback nofree nosync nounwind willreturn memory(argmem: readwrite) } 3650; CGSCC: attributes #[[ATTR3]] = { mustprogress nofree nosync nounwind willreturn } 3651; CGSCC: attributes #[[ATTR4]] = { mustprogress nofree norecurse nosync nounwind willreturn memory(none) } 3652; CGSCC: attributes #[[ATTR5]] = { mustprogress nofree norecurse nosync nounwind willreturn } 3653; CGSCC: attributes #[[ATTR6]] = { mustprogress nofree norecurse nosync nounwind willreturn memory(write) } 3654; CGSCC: attributes #[[ATTR7]] = { mustprogress nofree norecurse nosync nounwind willreturn memory(read) } 3655; CGSCC: attributes #[[ATTR8]] = { nofree norecurse nosync nounwind memory(write) } 3656; CGSCC: attributes #[[ATTR9:[0-9]+]] = { allockind("alloc,uninitialized") allocsize(0) "alloc-family"="malloc" } 3657; CGSCC: attributes #[[ATTR10:[0-9]+]] = { allockind("free") "alloc-family"="malloc" } 3658; CGSCC: attributes #[[ATTR11:[0-9]+]] = { allockind("alloc,zeroed") allocsize(0,1) "alloc-family"="malloc" } 3659; CGSCC: attributes #[[ATTR12]] = { mustprogress nofree norecurse nosync nounwind willreturn uwtable } 3660; CGSCC: attributes #[[ATTR13]] = { mustprogress nofree norecurse nosync nounwind willreturn memory(argmem: readwrite) } 3661; CGSCC: attributes #[[ATTR14]] = { nofree nosync nounwind memory(argmem: readwrite) } 3662; CGSCC: attributes #[[ATTR15]] = { nofree nosync nounwind memory(none) } 3663; CGSCC: attributes #[[ATTR16]] = { mustprogress nofree nosync nounwind willreturn memory(none) } 3664; CGSCC: attributes #[[ATTR17]] = { nofree nosync nounwind } 3665; CGSCC: attributes #[[ATTR18:[0-9]+]] = { nocallback nofree nosync nounwind willreturn memory(inaccessiblemem: write) } 3666; CGSCC: attributes #[[ATTR19:[0-9]+]] = { nocallback nofree nounwind willreturn memory(argmem: write) } 3667; CGSCC: attributes #[[ATTR20]] = { nofree willreturn } 3668; CGSCC: attributes #[[ATTR21]] = { nofree nounwind willreturn memory(write) } 3669; CGSCC: attributes #[[ATTR22]] = { nocallback } 3670; CGSCC: attributes #[[ATTR23]] = { norecurse } 3671; CGSCC: attributes #[[ATTR24]] = { nounwind } 3672; CGSCC: attributes #[[ATTR25]] = { nofree nounwind } 3673; CGSCC: attributes #[[ATTR26]] = { nofree nounwind willreturn } 3674; CGSCC: attributes #[[ATTR27]] = { nofree } 3675; CGSCC: attributes #[[ATTR28]] = { nofree nosync willreturn } 3676;. 3677; TUNIT: [[META0:![0-9]+]] = !{i32 1, !"wchar_size", i32 4} 3678; TUNIT: [[META1:![0-9]+]] = !{i32 7, !"uwtable", i32 1} 3679; TUNIT: [[META2:![0-9]+]] = !{!"{{.*}}clang version {{.*}}"} 3680; TUNIT: [[TBAA3]] = !{[[META4:![0-9]+]], [[META4]], i64 0} 3681; TUNIT: [[META4]] = !{!"int", [[META5:![0-9]+]], i64 0} 3682; TUNIT: [[META5]] = !{!"omnipotent char", [[META6:![0-9]+]], i64 0} 3683; TUNIT: [[META6]] = !{!"Simple C/C++ TBAA"} 3684; TUNIT: [[TBAA7]] = !{[[META8:![0-9]+]], [[META9:![0-9]+]], i64 12} 3685; TUNIT: [[META8]] = !{!"S", [[META4]], i64 0, [[META4]], i64 4, [[META4]], i64 8, [[META9]], i64 12, [[META9]], i64 16, [[META9]], i64 20} 3686; TUNIT: [[META9]] = !{!"float", [[META5]], i64 0} 3687; TUNIT: [[TBAA10]] = !{[[META8]], [[META9]], i64 16} 3688; TUNIT: [[TBAA11]] = !{[[META8]], [[META9]], i64 20} 3689; TUNIT: [[TBAA12]] = !{[[META8]], [[META4]], i64 0} 3690; TUNIT: [[TBAA13]] = !{[[META8]], [[META4]], i64 4} 3691; TUNIT: [[TBAA14]] = !{[[META8]], [[META4]], i64 8} 3692; TUNIT: [[LOOP15]] = distinct !{[[LOOP15]], [[META16:![0-9]+]]} 3693; TUNIT: [[META16]] = !{!"llvm.loop.mustprogress"} 3694; TUNIT: [[LOOP17]] = distinct !{[[LOOP17]], [[META16]]} 3695; TUNIT: [[LOOP18]] = distinct !{[[LOOP18]], [[META16]]} 3696; TUNIT: [[TBAA19]] = !{[[META5]], [[META5]], i64 0} 3697; TUNIT: [[LOOP20]] = distinct !{[[LOOP20]], [[META16]]} 3698; TUNIT: [[LOOP21]] = distinct !{[[LOOP21]], [[META16]]} 3699; TUNIT: [[LOOP22]] = distinct !{[[LOOP22]], [[META16]]} 3700; TUNIT: [[LOOP23]] = distinct !{[[LOOP23]], [[META16]]} 3701; TUNIT: [[LOOP24]] = distinct !{[[LOOP24]], [[META16]]} 3702; TUNIT: [[LOOP25]] = distinct !{[[LOOP25]], [[META16]]} 3703; TUNIT: [[TBAA26]] = !{[[META9]], [[META9]], i64 0} 3704; TUNIT: [[LOOP27]] = distinct !{[[LOOP27]], [[META16]]} 3705; TUNIT: [[TBAA28]] = !{[[META29:![0-9]+]], [[META29]], i64 0} 3706; TUNIT: [[META29]] = !{!"long long", [[META5]], i64 0} 3707; TUNIT: [[LOOP30]] = distinct !{[[LOOP30]], [[META16]]} 3708; TUNIT: [[LOOP31]] = distinct !{[[LOOP31]], [[META16]]} 3709;. 3710; CGSCC: [[META0:![0-9]+]] = !{i32 1, !"wchar_size", i32 4} 3711; CGSCC: [[META1:![0-9]+]] = !{i32 7, !"uwtable", i32 1} 3712; CGSCC: [[META2:![0-9]+]] = !{!"{{.*}}clang version {{.*}}"} 3713; CGSCC: [[TBAA3]] = !{[[META4:![0-9]+]], [[META4]], i64 0} 3714; CGSCC: [[META4]] = !{!"int", [[META5:![0-9]+]], i64 0} 3715; CGSCC: [[META5]] = !{!"omnipotent char", [[META6:![0-9]+]], i64 0} 3716; CGSCC: [[META6]] = !{!"Simple C/C++ TBAA"} 3717; CGSCC: [[TBAA7]] = !{[[META8:![0-9]+]], [[META9:![0-9]+]], i64 12} 3718; CGSCC: [[META8]] = !{!"S", [[META4]], i64 0, [[META4]], i64 4, [[META4]], i64 8, [[META9]], i64 12, [[META9]], i64 16, [[META9]], i64 20} 3719; CGSCC: [[META9]] = !{!"float", [[META5]], i64 0} 3720; CGSCC: [[TBAA10]] = !{[[META8]], [[META9]], i64 16} 3721; CGSCC: [[TBAA11]] = !{[[META8]], [[META9]], i64 20} 3722; CGSCC: [[TBAA12]] = !{[[META8]], [[META4]], i64 0} 3723; CGSCC: [[TBAA13]] = !{[[META8]], [[META4]], i64 4} 3724; CGSCC: [[TBAA14]] = !{[[META8]], [[META4]], i64 8} 3725; CGSCC: [[TBAA15]] = !{[[META5]], [[META5]], i64 0} 3726; CGSCC: [[LOOP16]] = distinct !{[[LOOP16]], [[META17:![0-9]+]]} 3727; CGSCC: [[META17]] = !{!"llvm.loop.mustprogress"} 3728; CGSCC: [[TBAA18]] = !{[[META9]], [[META9]], i64 0} 3729; CGSCC: [[LOOP19]] = distinct !{[[LOOP19]], [[META17]]} 3730; CGSCC: [[TBAA20]] = !{[[META21:![0-9]+]], [[META21]], i64 0} 3731; CGSCC: [[META21]] = !{!"long long", [[META5]], i64 0} 3732; CGSCC: [[LOOP22]] = distinct !{[[LOOP22]], [[META17]]} 3733; CGSCC: [[LOOP23]] = distinct !{[[LOOP23]], [[META17]]} 3734; CGSCC: [[LOOP24]] = distinct !{[[LOOP24]], [[META17]]} 3735; CGSCC: [[LOOP25]] = distinct !{[[LOOP25]], [[META17]]} 3736; CGSCC: [[LOOP26]] = distinct !{[[LOOP26]], [[META17]]} 3737; CGSCC: [[LOOP27]] = distinct !{[[LOOP27]], [[META17]]} 3738; CGSCC: [[LOOP28]] = distinct !{[[LOOP28]], [[META17]]} 3739; CGSCC: [[LOOP29]] = distinct !{[[LOOP29]], [[META17]]} 3740; CGSCC: [[LOOP30]] = distinct !{[[LOOP30]], [[META17]]} 3741; CGSCC: [[LOOP31]] = distinct !{[[LOOP31]], [[META17]]} 3742;. 3743