1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py 2; RUN: opt < %s -passes='sroa<preserve-cfg>' -S | FileCheck %s --check-prefixes=CHECK,CHECK-PRESERVE-CFG 3; RUN: opt < %s -passes='sroa<modify-cfg>' -S | FileCheck %s --check-prefixes=CHECK,CHECK-MODIFY-CFG 4 5target datalayout = "e-p:64:64:64-p1:16:16:16-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:32:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-n8:16:32:64" 6 7declare void @llvm.lifetime.start.p0(i64, ptr nocapture) 8declare void @llvm.lifetime.end.p0(i64, ptr nocapture) 9 10define i32 @test0() { 11; CHECK-LABEL: @test0( 12; CHECK-NEXT: entry: 13; CHECK-NEXT: [[V2_INT:%.*]] = bitcast float 0.000000e+00 to i32 14; CHECK-NEXT: [[SUM1:%.*]] = add i32 0, [[V2_INT]] 15; CHECK-NEXT: ret i32 [[SUM1]] 16; 17entry: 18 %a1 = alloca i32 19 %a2 = alloca float 20 21 call void @llvm.lifetime.start.p0(i64 4, ptr %a1) 22 23 store i32 0, ptr %a1 24 %v1 = load i32, ptr %a1 25 26 call void @llvm.lifetime.end.p0(i64 4, ptr %a1) 27 28 call void @llvm.lifetime.start.p0(i64 4, ptr %a2) 29 30 store float 0.0, ptr %a2 31 %v2 = load float , ptr %a2 32 %v2.int = bitcast float %v2 to i32 33 %sum1 = add i32 %v1, %v2.int 34 35 call void @llvm.lifetime.end.p0(i64 4, ptr %a2) 36 37 ret i32 %sum1 38} 39 40define i32 @test1() { 41; CHECK-LABEL: @test1( 42; CHECK-NEXT: entry: 43; CHECK-NEXT: ret i32 0 44; 45entry: 46 %X = alloca { i32, float } 47 %Y = getelementptr { i32, float }, ptr %X, i64 0, i32 0 48 store i32 0, ptr %Y 49 %Z = load i32, ptr %Y 50 ret i32 %Z 51} 52 53define i64 @test2(i64 %X) { 54; CHECK-LABEL: @test2( 55; CHECK-NEXT: entry: 56; CHECK-NEXT: br label [[L2:%.*]] 57; CHECK: L2: 58; CHECK-NEXT: ret i64 [[X:%.*]] 59; 60entry: 61 %A = alloca [8 x i8] 62 store i64 %X, ptr %A 63 br label %L2 64 65L2: 66 %Z = load i64, ptr %A 67 ret i64 %Z 68} 69 70define i64 @test2_addrspacecast(i64 %X) { 71; CHECK-LABEL: @test2_addrspacecast( 72; CHECK-NEXT: entry: 73; CHECK-NEXT: br label [[L2:%.*]] 74; CHECK: L2: 75; CHECK-NEXT: ret i64 [[X:%.*]] 76; 77entry: 78 %A = alloca [8 x i8] 79 %B = addrspacecast ptr %A to ptr addrspace(1) 80 store i64 %X, ptr addrspace(1) %B 81 br label %L2 82 83L2: 84 %Z = load i64, ptr addrspace(1) %B 85 ret i64 %Z 86} 87 88define i64 @test2_addrspacecast_gep(i64 %X, i16 %idx) { 89; CHECK-LABEL: @test2_addrspacecast_gep( 90; CHECK-NEXT: entry: 91; CHECK-NEXT: br label [[L2:%.*]] 92; CHECK: L2: 93; CHECK-NEXT: ret i64 [[X:%.*]] 94; 95entry: 96 %A = alloca [256 x i8] 97 %B = addrspacecast ptr %A to ptr addrspace(1) 98 %gepA = getelementptr [256 x i8], ptr %A, i16 0, i16 32 99 %gepB = getelementptr i64, ptr addrspace(1) %B, i16 4 100 store i64 %X, ptr addrspace(1) %gepB, align 1 101 br label %L2 102 103L2: 104 %Z = load i64, ptr %gepA, align 1 105 ret i64 %Z 106} 107 108; Avoid crashing when load/storing at at different offsets. 109define i64 @test2_addrspacecast_gep_offset(i64 %X) { 110; CHECK-LABEL: @test2_addrspacecast_gep_offset( 111; CHECK-NEXT: entry: 112; CHECK-NEXT: [[A_SROA_0:%.*]] = alloca [10 x i8], align 1 113; CHECK-NEXT: [[A_SROA_0_2_GEPB_SROA_IDX:%.*]] = getelementptr inbounds i8, ptr [[A_SROA_0]], i16 2 114; CHECK-NEXT: [[A_SROA_0_2_GEPB_SROA_CAST:%.*]] = addrspacecast ptr [[A_SROA_0_2_GEPB_SROA_IDX]] to ptr addrspace(1) 115; CHECK-NEXT: store i64 [[X:%.*]], ptr addrspace(1) [[A_SROA_0_2_GEPB_SROA_CAST]], align 1 116; CHECK-NEXT: br label [[L2:%.*]] 117; CHECK: L2: 118; CHECK-NEXT: [[A_SROA_0_0_A_SROA_0_30_Z:%.*]] = load i64, ptr [[A_SROA_0]], align 1 119; CHECK-NEXT: ret i64 [[A_SROA_0_0_A_SROA_0_30_Z]] 120; 121entry: 122 %A = alloca [256 x i8] 123 %B = addrspacecast ptr %A to ptr addrspace(1) 124 %gepA = getelementptr [256 x i8], ptr %A, i16 0, i16 30 125 %gepB = getelementptr i64, ptr addrspace(1) %B, i16 4 126 store i64 %X, ptr addrspace(1) %gepB, align 1 127 br label %L2 128 129L2: 130 %Z = load i64, ptr %gepA, align 1 131 ret i64 %Z 132} 133 134define void @test3(ptr %dst, ptr align 8 %src) { 135; CHECK-LABEL: @test3( 136; CHECK-NEXT: entry: 137; CHECK-NEXT: [[A_SROA_0:%.*]] = alloca [42 x i8], align 1 138; CHECK-NEXT: [[A_SROA_3:%.*]] = alloca [99 x i8], align 1 139; CHECK-NEXT: [[A_SROA_32:%.*]] = alloca [16 x i8], align 1 140; CHECK-NEXT: [[A_SROA_15:%.*]] = alloca [42 x i8], align 1 141; CHECK-NEXT: [[A_SROA_16:%.*]] = alloca [7 x i8], align 1 142; CHECK-NEXT: [[A_SROA_235:%.*]] = alloca [7 x i8], align 1 143; CHECK-NEXT: [[A_SROA_31:%.*]] = alloca [85 x i8], align 1 144; CHECK-NEXT: call void @llvm.memcpy.p0.p0.i32(ptr align 1 [[A_SROA_0]], ptr align 8 [[SRC:%.*]], i32 42, i1 false), !tbaa [[TBAA0:![0-9]+]] 145; CHECK-NEXT: [[A_SROA_2_0_SRC_SROA_IDX:%.*]] = getelementptr inbounds i8, ptr [[SRC]], i64 42 146; CHECK-NEXT: [[A_SROA_2_0_COPYLOAD:%.*]] = load i8, ptr [[A_SROA_2_0_SRC_SROA_IDX]], align 2, !tbaa [[TBAA0]] 147; CHECK-NEXT: [[A_SROA_3_0_SRC_SROA_IDX:%.*]] = getelementptr inbounds i8, ptr [[SRC]], i64 43 148; CHECK-NEXT: call void @llvm.memcpy.p0.p0.i32(ptr align 1 [[A_SROA_3]], ptr align 1 [[A_SROA_3_0_SRC_SROA_IDX]], i32 99, i1 false), !tbaa [[TBAA0]] 149; CHECK-NEXT: [[A_SROA_32_0_SRC_SROA_IDX:%.*]] = getelementptr inbounds i8, ptr [[SRC]], i64 142 150; CHECK-NEXT: call void @llvm.memcpy.p0.p0.i32(ptr align 1 [[A_SROA_32]], ptr align 2 [[A_SROA_32_0_SRC_SROA_IDX]], i32 16, i1 false), !tbaa [[TBAA0]] 151; CHECK-NEXT: [[A_SROA_15_0_SRC_SROA_IDX:%.*]] = getelementptr inbounds i8, ptr [[SRC]], i64 158 152; CHECK-NEXT: call void @llvm.memcpy.p0.p0.i32(ptr align 1 [[A_SROA_15]], ptr align 2 [[A_SROA_15_0_SRC_SROA_IDX]], i32 42, i1 false), !tbaa [[TBAA0]] 153; CHECK-NEXT: [[A_SROA_16_0_SRC_SROA_IDX:%.*]] = getelementptr inbounds i8, ptr [[SRC]], i64 200 154; CHECK-NEXT: call void @llvm.memcpy.p0.p0.i32(ptr align 1 [[A_SROA_16]], ptr align 8 [[A_SROA_16_0_SRC_SROA_IDX]], i32 7, i1 false), !tbaa [[TBAA0]] 155; CHECK-NEXT: [[A_SROA_23_0_SRC_SROA_IDX:%.*]] = getelementptr inbounds i8, ptr [[SRC]], i64 207 156; CHECK-NEXT: [[A_SROA_23_0_COPYLOAD:%.*]] = load i8, ptr [[A_SROA_23_0_SRC_SROA_IDX]], align 1, !tbaa [[TBAA0]] 157; CHECK-NEXT: [[A_SROA_235_0_SRC_SROA_IDX:%.*]] = getelementptr inbounds i8, ptr [[SRC]], i64 208 158; CHECK-NEXT: call void @llvm.memcpy.p0.p0.i32(ptr align 1 [[A_SROA_235]], ptr align 8 [[A_SROA_235_0_SRC_SROA_IDX]], i32 7, i1 false), !tbaa [[TBAA0]] 159; CHECK-NEXT: [[A_SROA_31_0_SRC_SROA_IDX:%.*]] = getelementptr inbounds i8, ptr [[SRC]], i64 215 160; CHECK-NEXT: call void @llvm.memcpy.p0.p0.i32(ptr align 1 [[A_SROA_31]], ptr align 1 [[A_SROA_31_0_SRC_SROA_IDX]], i32 85, i1 false), !tbaa [[TBAA0]] 161; CHECK-NEXT: store i8 1, ptr [[A_SROA_32]], align 1, !tbaa [[TBAA3:![0-9]+]] 162; CHECK-NEXT: store i16 1, ptr [[A_SROA_32]], align 1, !tbaa [[TBAA5:![0-9]+]] 163; CHECK-NEXT: store i32 1, ptr [[A_SROA_32]], align 1, !tbaa [[TBAA7:![0-9]+]] 164; CHECK-NEXT: store i64 1, ptr [[A_SROA_32]], align 1, !tbaa [[TBAA9:![0-9]+]] 165; CHECK-NEXT: [[A_SROA_32_1_OVERLAP_2_I8_SROA_IDX:%.*]] = getelementptr inbounds i8, ptr [[A_SROA_32]], i64 1 166; CHECK-NEXT: store i64 2, ptr [[A_SROA_32_1_OVERLAP_2_I8_SROA_IDX]], align 1, !tbaa [[TBAA11:![0-9]+]] 167; CHECK-NEXT: [[A_SROA_32_2_OVERLAP_3_I8_SROA_IDX:%.*]] = getelementptr inbounds i8, ptr [[A_SROA_32]], i64 2 168; CHECK-NEXT: store i64 3, ptr [[A_SROA_32_2_OVERLAP_3_I8_SROA_IDX]], align 1, !tbaa [[TBAA13:![0-9]+]] 169; CHECK-NEXT: [[A_SROA_32_3_OVERLAP_4_I8_SROA_IDX:%.*]] = getelementptr inbounds i8, ptr [[A_SROA_32]], i64 3 170; CHECK-NEXT: store i64 4, ptr [[A_SROA_32_3_OVERLAP_4_I8_SROA_IDX]], align 1, !tbaa [[TBAA15:![0-9]+]] 171; CHECK-NEXT: [[A_SROA_32_4_OVERLAP_5_I8_SROA_IDX:%.*]] = getelementptr inbounds i8, ptr [[A_SROA_32]], i64 4 172; CHECK-NEXT: store i64 5, ptr [[A_SROA_32_4_OVERLAP_5_I8_SROA_IDX]], align 1, !tbaa [[TBAA17:![0-9]+]] 173; CHECK-NEXT: [[A_SROA_32_5_OVERLAP_6_I8_SROA_IDX:%.*]] = getelementptr inbounds i8, ptr [[A_SROA_32]], i64 5 174; CHECK-NEXT: store i64 6, ptr [[A_SROA_32_5_OVERLAP_6_I8_SROA_IDX]], align 1, !tbaa [[TBAA19:![0-9]+]] 175; CHECK-NEXT: [[A_SROA_32_6_OVERLAP_7_I8_SROA_IDX:%.*]] = getelementptr inbounds i8, ptr [[A_SROA_32]], i64 6 176; CHECK-NEXT: store i64 7, ptr [[A_SROA_32_6_OVERLAP_7_I8_SROA_IDX]], align 1, !tbaa [[TBAA21:![0-9]+]] 177; CHECK-NEXT: [[A_SROA_32_7_OVERLAP_8_I8_SROA_IDX:%.*]] = getelementptr inbounds i8, ptr [[A_SROA_32]], i64 7 178; CHECK-NEXT: store i64 8, ptr [[A_SROA_32_7_OVERLAP_8_I8_SROA_IDX]], align 1, !tbaa [[TBAA23:![0-9]+]] 179; CHECK-NEXT: [[A_SROA_32_8_OVERLAP_9_I8_SROA_IDX:%.*]] = getelementptr inbounds i8, ptr [[A_SROA_32]], i64 8 180; CHECK-NEXT: store i64 9, ptr [[A_SROA_32_8_OVERLAP_9_I8_SROA_IDX]], align 1, !tbaa [[TBAA25:![0-9]+]] 181; CHECK-NEXT: store i8 1, ptr [[A_SROA_16]], align 1, !tbaa [[TBAA27:![0-9]+]] 182; CHECK-NEXT: store i16 1, ptr [[A_SROA_16]], align 1, !tbaa [[TBAA29:![0-9]+]] 183; CHECK-NEXT: store i32 1, ptr [[A_SROA_16]], align 1, !tbaa [[TBAA31:![0-9]+]] 184; CHECK-NEXT: [[A_SROA_16_1_OVERLAP2_1_1_I8_SROA_IDX:%.*]] = getelementptr inbounds i8, ptr [[A_SROA_16]], i64 1 185; CHECK-NEXT: store i32 2, ptr [[A_SROA_16_1_OVERLAP2_1_1_I8_SROA_IDX]], align 1, !tbaa [[TBAA33:![0-9]+]] 186; CHECK-NEXT: [[A_SROA_16_2_OVERLAP2_1_2_I8_SROA_IDX:%.*]] = getelementptr inbounds i8, ptr [[A_SROA_16]], i64 2 187; CHECK-NEXT: store i32 3, ptr [[A_SROA_16_2_OVERLAP2_1_2_I8_SROA_IDX]], align 1, !tbaa [[TBAA35:![0-9]+]] 188; CHECK-NEXT: [[A_SROA_16_3_OVERLAP2_1_3_I8_SROA_IDX:%.*]] = getelementptr inbounds i8, ptr [[A_SROA_16]], i64 3 189; CHECK-NEXT: store i32 4, ptr [[A_SROA_16_3_OVERLAP2_1_3_I8_SROA_IDX]], align 1, !tbaa [[TBAA37:![0-9]+]] 190; CHECK-NEXT: store i32 1, ptr [[A_SROA_235]], align 1, !tbaa [[TBAA39:![0-9]+]] 191; CHECK-NEXT: [[A_SROA_235_1_OVERLAP2_2_1_I8_SROA_IDX11:%.*]] = getelementptr inbounds i8, ptr [[A_SROA_235]], i64 1 192; CHECK-NEXT: store i8 1, ptr [[A_SROA_235_1_OVERLAP2_2_1_I8_SROA_IDX11]], align 1, !tbaa [[TBAA41:![0-9]+]] 193; CHECK-NEXT: [[A_SROA_235_1_OVERLAP2_2_1_I8_SROA_IDX10:%.*]] = getelementptr inbounds i8, ptr [[A_SROA_235]], i64 1 194; CHECK-NEXT: store i16 1, ptr [[A_SROA_235_1_OVERLAP2_2_1_I8_SROA_IDX10]], align 1, !tbaa [[TBAA43:![0-9]+]] 195; CHECK-NEXT: [[A_SROA_235_1_OVERLAP2_2_1_I8_SROA_IDX:%.*]] = getelementptr inbounds i8, ptr [[A_SROA_235]], i64 1 196; CHECK-NEXT: store i32 1, ptr [[A_SROA_235_1_OVERLAP2_2_1_I8_SROA_IDX]], align 1, !tbaa [[TBAA45:![0-9]+]] 197; CHECK-NEXT: [[A_SROA_235_2_OVERLAP2_2_2_I8_SROA_IDX:%.*]] = getelementptr inbounds i8, ptr [[A_SROA_235]], i64 2 198; CHECK-NEXT: store i32 3, ptr [[A_SROA_235_2_OVERLAP2_2_2_I8_SROA_IDX]], align 1, !tbaa [[TBAA47:![0-9]+]] 199; CHECK-NEXT: [[A_SROA_235_3_OVERLAP2_2_3_I8_SROA_IDX:%.*]] = getelementptr inbounds i8, ptr [[A_SROA_235]], i64 3 200; CHECK-NEXT: store i32 4, ptr [[A_SROA_235_3_OVERLAP2_2_3_I8_SROA_IDX]], align 1, !tbaa [[TBAA49:![0-9]+]] 201; CHECK-NEXT: [[A_SROA_15_197_OVERLAP2_PREFIX_SROA_IDX:%.*]] = getelementptr inbounds i8, ptr [[A_SROA_15]], i64 39 202; CHECK-NEXT: call void @llvm.memcpy.p0.p0.i32(ptr align 1 [[A_SROA_15_197_OVERLAP2_PREFIX_SROA_IDX]], ptr align 1 [[SRC]], i32 3, i1 false), !tbaa [[TBAA51:![0-9]+]] 203; CHECK-NEXT: [[A_SROA_16_197_SRC_SROA_IDX:%.*]] = getelementptr inbounds i8, ptr [[SRC]], i64 3 204; CHECK-NEXT: call void @llvm.memcpy.p0.p0.i32(ptr align 1 [[A_SROA_16]], ptr align 1 [[A_SROA_16_197_SRC_SROA_IDX]], i32 5, i1 false), !tbaa [[TBAA51]] 205; CHECK-NEXT: [[A_SROA_16_2_OVERLAP2_1_2_I8_SROA_IDX12:%.*]] = getelementptr inbounds i8, ptr [[A_SROA_16]], i64 2 206; CHECK-NEXT: call void @llvm.memset.p0.i32(ptr align 1 [[A_SROA_16_2_OVERLAP2_1_2_I8_SROA_IDX12]], i8 42, i32 5, i1 false), !tbaa [[TBAA53:![0-9]+]] 207; CHECK-NEXT: call void @llvm.memset.p0.i32(ptr align 1 [[A_SROA_235]], i8 42, i32 2, i1 false), !tbaa [[TBAA53]] 208; CHECK-NEXT: [[A_SROA_235_209_OVERLAP2_2_1_I8_SROA_IDX8:%.*]] = getelementptr inbounds i8, ptr [[A_SROA_235]], i64 1 209; CHECK-NEXT: call void @llvm.memcpy.p0.p0.i32(ptr align 1 [[A_SROA_235_209_OVERLAP2_2_1_I8_SROA_IDX8]], ptr align 1 [[SRC]], i32 5, i1 false), !tbaa [[TBAA55:![0-9]+]] 210; CHECK-NEXT: [[A_SROA_235_210_OVERLAP2_2_2_I8_SROA_IDX9:%.*]] = getelementptr inbounds i8, ptr [[A_SROA_235]], i64 2 211; CHECK-NEXT: call void @llvm.memcpy.p0.p0.i32(ptr align 1 [[A_SROA_235_210_OVERLAP2_2_2_I8_SROA_IDX9]], ptr align 1 [[SRC]], i32 5, i1 false), !tbaa [[TBAA57:![0-9]+]] 212; CHECK-NEXT: [[A_SROA_31_210_SRC_SROA_IDX:%.*]] = getelementptr inbounds i8, ptr [[SRC]], i64 5 213; CHECK-NEXT: call void @llvm.memcpy.p0.p0.i32(ptr align 1 [[A_SROA_31]], ptr align 1 [[A_SROA_31_210_SRC_SROA_IDX]], i32 3, i1 false), !tbaa [[TBAA57]] 214; CHECK-NEXT: call void @llvm.memcpy.p0.p0.i32(ptr align 1 [[DST:%.*]], ptr align 1 [[A_SROA_0]], i32 42, i1 false), !tbaa [[TBAA59:![0-9]+]] 215; CHECK-NEXT: [[A_SROA_2_0_DST_SROA_IDX:%.*]] = getelementptr inbounds i8, ptr [[DST]], i64 42 216; CHECK-NEXT: store i8 0, ptr [[A_SROA_2_0_DST_SROA_IDX]], align 1, !tbaa [[TBAA59]] 217; CHECK-NEXT: [[A_SROA_3_0_DST_SROA_IDX:%.*]] = getelementptr inbounds i8, ptr [[DST]], i64 43 218; CHECK-NEXT: call void @llvm.memcpy.p0.p0.i32(ptr align 1 [[A_SROA_3_0_DST_SROA_IDX]], ptr align 1 [[A_SROA_3]], i32 99, i1 false), !tbaa [[TBAA59]] 219; CHECK-NEXT: [[A_SROA_32_0_DST_SROA_IDX:%.*]] = getelementptr inbounds i8, ptr [[DST]], i64 142 220; CHECK-NEXT: call void @llvm.memcpy.p0.p0.i32(ptr align 1 [[A_SROA_32_0_DST_SROA_IDX]], ptr align 1 [[A_SROA_32]], i32 16, i1 false), !tbaa [[TBAA59]] 221; CHECK-NEXT: [[A_SROA_15_0_DST_SROA_IDX:%.*]] = getelementptr inbounds i8, ptr [[DST]], i64 158 222; CHECK-NEXT: call void @llvm.memcpy.p0.p0.i32(ptr align 1 [[A_SROA_15_0_DST_SROA_IDX]], ptr align 1 [[A_SROA_15]], i32 42, i1 false), !tbaa [[TBAA59]] 223; CHECK-NEXT: [[A_SROA_16_0_DST_SROA_IDX:%.*]] = getelementptr inbounds i8, ptr [[DST]], i64 200 224; CHECK-NEXT: call void @llvm.memcpy.p0.p0.i32(ptr align 1 [[A_SROA_16_0_DST_SROA_IDX]], ptr align 1 [[A_SROA_16]], i32 7, i1 false), !tbaa [[TBAA59]] 225; CHECK-NEXT: [[A_SROA_23_0_DST_SROA_IDX:%.*]] = getelementptr inbounds i8, ptr [[DST]], i64 207 226; CHECK-NEXT: store i8 42, ptr [[A_SROA_23_0_DST_SROA_IDX]], align 1, !tbaa [[TBAA59]] 227; CHECK-NEXT: [[A_SROA_235_0_DST_SROA_IDX:%.*]] = getelementptr inbounds i8, ptr [[DST]], i64 208 228; CHECK-NEXT: call void @llvm.memcpy.p0.p0.i32(ptr align 1 [[A_SROA_235_0_DST_SROA_IDX]], ptr align 1 [[A_SROA_235]], i32 7, i1 false), !tbaa [[TBAA59]] 229; CHECK-NEXT: [[A_SROA_31_0_DST_SROA_IDX:%.*]] = getelementptr inbounds i8, ptr [[DST]], i64 215 230; CHECK-NEXT: call void @llvm.memcpy.p0.p0.i32(ptr align 1 [[A_SROA_31_0_DST_SROA_IDX]], ptr align 1 [[A_SROA_31]], i32 85, i1 false), !tbaa [[TBAA59]] 231; CHECK-NEXT: ret void 232; 233entry: 234 %a = alloca [300 x i8] 235 236 call void @llvm.memcpy.p0.p0.i32(ptr %a, ptr align 8 %src, i32 300, i1 false), !tbaa !0 237 238 ; Clobber a single element of the array, this should be promotable, and be deleted. 239 %c = getelementptr [300 x i8], ptr %a, i64 0, i64 42 240 store i8 0, ptr %c 241 242 ; Make a sequence of overlapping stores to the array. These overlap both in 243 ; forward strides and in shrinking accesses. 244 %overlap.1.i8 = getelementptr [300 x i8], ptr %a, i64 0, i64 142 245 %overlap.2.i8 = getelementptr [300 x i8], ptr %a, i64 0, i64 143 246 %overlap.3.i8 = getelementptr [300 x i8], ptr %a, i64 0, i64 144 247 %overlap.4.i8 = getelementptr [300 x i8], ptr %a, i64 0, i64 145 248 %overlap.5.i8 = getelementptr [300 x i8], ptr %a, i64 0, i64 146 249 %overlap.6.i8 = getelementptr [300 x i8], ptr %a, i64 0, i64 147 250 %overlap.7.i8 = getelementptr [300 x i8], ptr %a, i64 0, i64 148 251 %overlap.8.i8 = getelementptr [300 x i8], ptr %a, i64 0, i64 149 252 %overlap.9.i8 = getelementptr [300 x i8], ptr %a, i64 0, i64 150 253 store i8 1, ptr %overlap.1.i8, !tbaa !3 254 store i16 1, ptr %overlap.1.i8, !tbaa !5 255 store i32 1, ptr %overlap.1.i8, !tbaa !7 256 store i64 1, ptr %overlap.1.i8, !tbaa !9 257 store i64 2, ptr %overlap.2.i8, !tbaa !11 258 store i64 3, ptr %overlap.3.i8, !tbaa !13 259 store i64 4, ptr %overlap.4.i8, !tbaa !15 260 store i64 5, ptr %overlap.5.i8, !tbaa !17 261 store i64 6, ptr %overlap.6.i8, !tbaa !19 262 store i64 7, ptr %overlap.7.i8, !tbaa !21 263 store i64 8, ptr %overlap.8.i8, !tbaa !23 264 store i64 9, ptr %overlap.9.i8, !tbaa !25 265 266 ; Make two sequences of overlapping stores with more gaps and irregularities. 267 %overlap2.1.0.i8 = getelementptr [300 x i8], ptr %a, i64 0, i64 200 268 %overlap2.1.1.i8 = getelementptr [300 x i8], ptr %a, i64 0, i64 201 269 %overlap2.1.2.i8 = getelementptr [300 x i8], ptr %a, i64 0, i64 202 270 %overlap2.1.3.i8 = getelementptr [300 x i8], ptr %a, i64 0, i64 203 271 272 %overlap2.2.0.i8 = getelementptr [300 x i8], ptr %a, i64 0, i64 208 273 %overlap2.2.1.i8 = getelementptr [300 x i8], ptr %a, i64 0, i64 209 274 %overlap2.2.2.i8 = getelementptr [300 x i8], ptr %a, i64 0, i64 210 275 %overlap2.2.3.i8 = getelementptr [300 x i8], ptr %a, i64 0, i64 211 276 277 store i8 1, ptr %overlap2.1.0.i8, !tbaa !27 278 store i16 1, ptr %overlap2.1.0.i8, !tbaa !29 279 store i32 1, ptr %overlap2.1.0.i8, !tbaa !31 280 store i32 2, ptr %overlap2.1.1.i8, !tbaa !33 281 store i32 3, ptr %overlap2.1.2.i8, !tbaa !35 282 store i32 4, ptr %overlap2.1.3.i8, !tbaa !37 283 284 store i32 1, ptr %overlap2.2.0.i8, !tbaa !39 285 store i8 1, ptr %overlap2.2.1.i8, !tbaa !41 286 store i16 1, ptr %overlap2.2.1.i8, !tbaa !43 287 store i32 1, ptr %overlap2.2.1.i8, !tbaa !45 288 store i32 3, ptr %overlap2.2.2.i8, !tbaa !47 289 store i32 4, ptr %overlap2.2.3.i8, !tbaa !49 290 291 %overlap2.prefix = getelementptr i8, ptr %overlap2.1.1.i8, i64 -4 292 call void @llvm.memcpy.p0.p0.i32(ptr %overlap2.prefix, ptr %src, i32 8, i1 false), !tbaa !51 293 294 ; Bridge between the overlapping areas 295 call void @llvm.memset.p0.i32(ptr %overlap2.1.2.i8, i8 42, i32 8, i1 false), !tbaa !53 296; ...promoted i8 store... 297 298 ; Entirely within the second overlap. 299 call void @llvm.memcpy.p0.p0.i32(ptr %overlap2.2.1.i8, ptr %src, i32 5, i1 false), !tbaa !55 300 301 ; Trailing past the second overlap. 302 call void @llvm.memcpy.p0.p0.i32(ptr %overlap2.2.2.i8, ptr %src, i32 8, i1 false), !tbaa !57 303 304 call void @llvm.memcpy.p0.p0.i32(ptr %dst, ptr %a, i32 300, i1 false), !tbaa !59 305 306 ret void 307} 308 309define void @test4(ptr %dst, ptr %src) { 310; CHECK-LABEL: @test4( 311; CHECK-NEXT: entry: 312; CHECK-NEXT: [[A_SROA_0:%.*]] = alloca [20 x i8], align 1 313; CHECK-NEXT: [[A_SROA_2_SROA_4:%.*]] = alloca [7 x i8], align 1 314; CHECK-NEXT: [[A_SROA_3:%.*]] = alloca [10 x i8], align 1 315; CHECK-NEXT: [[A_SROA_31_SROA_5:%.*]] = alloca [7 x i8], align 1 316; CHECK-NEXT: [[A_SROA_6_SROA_4:%.*]] = alloca [7 x i8], align 1 317; CHECK-NEXT: [[A_SROA_7:%.*]] = alloca [40 x i8], align 1 318; CHECK-NEXT: call void @llvm.memcpy.p0.p0.i32(ptr align 1 [[A_SROA_0]], ptr align 1 [[SRC:%.*]], i32 20, i1 false), !tbaa [[TBAA0]] 319; CHECK-NEXT: [[A_SROA_2_0_SRC_SROA_IDX:%.*]] = getelementptr inbounds i8, ptr [[SRC]], i64 20 320; CHECK-NEXT: [[A_SROA_2_SROA_0_0_COPYLOAD:%.*]] = load i16, ptr [[A_SROA_2_0_SRC_SROA_IDX]], align 1, !tbaa [[TBAA0]] 321; CHECK-NEXT: [[A_SROA_2_SROA_3_0_A_SROA_2_0_SRC_SROA_IDX_SROA_IDX:%.*]] = getelementptr inbounds i8, ptr [[A_SROA_2_0_SRC_SROA_IDX]], i64 2 322; CHECK-NEXT: [[A_SROA_2_SROA_3_0_COPYLOAD:%.*]] = load i8, ptr [[A_SROA_2_SROA_3_0_A_SROA_2_0_SRC_SROA_IDX_SROA_IDX]], align 1, !tbaa [[TBAA0]] 323; CHECK-NEXT: [[A_SROA_2_SROA_4_0_A_SROA_2_0_SRC_SROA_IDX_SROA_IDX:%.*]] = getelementptr inbounds i8, ptr [[A_SROA_2_0_SRC_SROA_IDX]], i64 3 324; CHECK-NEXT: call void @llvm.memcpy.p0.p0.i32(ptr align 1 [[A_SROA_2_SROA_4]], ptr align 1 [[A_SROA_2_SROA_4_0_A_SROA_2_0_SRC_SROA_IDX_SROA_IDX]], i32 7, i1 false), !tbaa [[TBAA0]] 325; CHECK-NEXT: [[A_SROA_3_0_SRC_SROA_IDX:%.*]] = getelementptr inbounds i8, ptr [[SRC]], i64 30 326; CHECK-NEXT: call void @llvm.memcpy.p0.p0.i32(ptr align 1 [[A_SROA_3]], ptr align 1 [[A_SROA_3_0_SRC_SROA_IDX]], i32 10, i1 false), !tbaa [[TBAA0]] 327; CHECK-NEXT: [[A_SROA_31_0_SRC_SROA_IDX:%.*]] = getelementptr inbounds i8, ptr [[SRC]], i64 40 328; CHECK-NEXT: [[A_SROA_31_SROA_0_0_COPYLOAD:%.*]] = load i16, ptr [[A_SROA_31_0_SRC_SROA_IDX]], align 1, !tbaa [[TBAA0]] 329; CHECK-NEXT: [[A_SROA_31_SROA_4_0_A_SROA_31_0_SRC_SROA_IDX_SROA_IDX:%.*]] = getelementptr inbounds i8, ptr [[A_SROA_31_0_SRC_SROA_IDX]], i64 2 330; CHECK-NEXT: [[A_SROA_31_SROA_4_0_COPYLOAD:%.*]] = load i8, ptr [[A_SROA_31_SROA_4_0_A_SROA_31_0_SRC_SROA_IDX_SROA_IDX]], align 1, !tbaa [[TBAA0]] 331; CHECK-NEXT: [[A_SROA_31_SROA_5_0_A_SROA_31_0_SRC_SROA_IDX_SROA_IDX:%.*]] = getelementptr inbounds i8, ptr [[A_SROA_31_0_SRC_SROA_IDX]], i64 3 332; CHECK-NEXT: call void @llvm.memcpy.p0.p0.i32(ptr align 1 [[A_SROA_31_SROA_5]], ptr align 1 [[A_SROA_31_SROA_5_0_A_SROA_31_0_SRC_SROA_IDX_SROA_IDX]], i32 7, i1 false), !tbaa [[TBAA0]] 333; CHECK-NEXT: [[A_SROA_6_0_SRC_SROA_IDX:%.*]] = getelementptr inbounds i8, ptr [[SRC]], i64 50 334; CHECK-NEXT: [[A_SROA_6_SROA_0_0_COPYLOAD:%.*]] = load i16, ptr [[A_SROA_6_0_SRC_SROA_IDX]], align 1, !tbaa [[TBAA0]] 335; CHECK-NEXT: [[A_SROA_6_SROA_3_0_A_SROA_6_0_SRC_SROA_IDX_SROA_IDX:%.*]] = getelementptr inbounds i8, ptr [[A_SROA_6_0_SRC_SROA_IDX]], i64 2 336; CHECK-NEXT: [[A_SROA_6_SROA_3_0_COPYLOAD:%.*]] = load i8, ptr [[A_SROA_6_SROA_3_0_A_SROA_6_0_SRC_SROA_IDX_SROA_IDX]], align 1, !tbaa [[TBAA0]] 337; CHECK-NEXT: [[A_SROA_6_SROA_4_0_A_SROA_6_0_SRC_SROA_IDX_SROA_IDX:%.*]] = getelementptr inbounds i8, ptr [[A_SROA_6_0_SRC_SROA_IDX]], i64 3 338; CHECK-NEXT: call void @llvm.memcpy.p0.p0.i32(ptr align 1 [[A_SROA_6_SROA_4]], ptr align 1 [[A_SROA_6_SROA_4_0_A_SROA_6_0_SRC_SROA_IDX_SROA_IDX]], i32 7, i1 false), !tbaa [[TBAA0]] 339; CHECK-NEXT: [[A_SROA_7_0_SRC_SROA_IDX:%.*]] = getelementptr inbounds i8, ptr [[SRC]], i64 60 340; CHECK-NEXT: call void @llvm.memcpy.p0.p0.i32(ptr align 1 [[A_SROA_7]], ptr align 1 [[A_SROA_7_0_SRC_SROA_IDX]], i32 40, i1 false), !tbaa [[TBAA0]] 341; CHECK-NEXT: call void @llvm.memcpy.p0.p0.i32(ptr align 1 [[A_SROA_31_SROA_5]], ptr align 1 [[A_SROA_2_SROA_4]], i32 7, i1 false), !tbaa [[TBAA3]] 342; CHECK-NEXT: call void @llvm.memcpy.p0.p0.i32(ptr align 1 [[A_SROA_31_SROA_5]], ptr align 1 [[A_SROA_6_SROA_4]], i32 7, i1 false), !tbaa [[TBAA5]] 343; CHECK-NEXT: call void @llvm.memcpy.p0.p0.i32(ptr align 1 [[DST:%.*]], ptr align 1 [[A_SROA_0]], i32 20, i1 false), !tbaa [[TBAA7]] 344; CHECK-NEXT: [[A_SROA_2_0_DST_SROA_IDX:%.*]] = getelementptr inbounds i8, ptr [[DST]], i64 20 345; CHECK-NEXT: store i16 [[A_SROA_2_SROA_0_0_COPYLOAD]], ptr [[A_SROA_2_0_DST_SROA_IDX]], align 1, !tbaa [[TBAA7]] 346; CHECK-NEXT: [[A_SROA_2_SROA_3_0_A_SROA_2_0_DST_SROA_IDX_SROA_IDX:%.*]] = getelementptr inbounds i8, ptr [[A_SROA_2_0_DST_SROA_IDX]], i64 2 347; CHECK-NEXT: store i8 [[A_SROA_2_SROA_3_0_COPYLOAD]], ptr [[A_SROA_2_SROA_3_0_A_SROA_2_0_DST_SROA_IDX_SROA_IDX]], align 1, !tbaa [[TBAA7]] 348; CHECK-NEXT: [[A_SROA_2_SROA_4_0_A_SROA_2_0_DST_SROA_IDX_SROA_IDX:%.*]] = getelementptr inbounds i8, ptr [[A_SROA_2_0_DST_SROA_IDX]], i64 3 349; CHECK-NEXT: call void @llvm.memcpy.p0.p0.i32(ptr align 1 [[A_SROA_2_SROA_4_0_A_SROA_2_0_DST_SROA_IDX_SROA_IDX]], ptr align 1 [[A_SROA_2_SROA_4]], i32 7, i1 false), !tbaa [[TBAA7]] 350; CHECK-NEXT: [[A_SROA_3_0_DST_SROA_IDX:%.*]] = getelementptr inbounds i8, ptr [[DST]], i64 30 351; CHECK-NEXT: call void @llvm.memcpy.p0.p0.i32(ptr align 1 [[A_SROA_3_0_DST_SROA_IDX]], ptr align 1 [[A_SROA_3]], i32 10, i1 false), !tbaa [[TBAA7]] 352; CHECK-NEXT: [[A_SROA_31_0_DST_SROA_IDX:%.*]] = getelementptr inbounds i8, ptr [[DST]], i64 40 353; CHECK-NEXT: store i16 [[A_SROA_6_SROA_0_0_COPYLOAD]], ptr [[A_SROA_31_0_DST_SROA_IDX]], align 1, !tbaa [[TBAA7]] 354; CHECK-NEXT: [[A_SROA_31_SROA_4_0_A_SROA_31_0_DST_SROA_IDX_SROA_IDX:%.*]] = getelementptr inbounds i8, ptr [[A_SROA_31_0_DST_SROA_IDX]], i64 2 355; CHECK-NEXT: store i8 [[A_SROA_6_SROA_3_0_COPYLOAD]], ptr [[A_SROA_31_SROA_4_0_A_SROA_31_0_DST_SROA_IDX_SROA_IDX]], align 1, !tbaa [[TBAA7]] 356; CHECK-NEXT: [[A_SROA_31_SROA_5_0_A_SROA_31_0_DST_SROA_IDX_SROA_IDX:%.*]] = getelementptr inbounds i8, ptr [[A_SROA_31_0_DST_SROA_IDX]], i64 3 357; CHECK-NEXT: call void @llvm.memcpy.p0.p0.i32(ptr align 1 [[A_SROA_31_SROA_5_0_A_SROA_31_0_DST_SROA_IDX_SROA_IDX]], ptr align 1 [[A_SROA_31_SROA_5]], i32 7, i1 false), !tbaa [[TBAA7]] 358; CHECK-NEXT: [[A_SROA_6_0_DST_SROA_IDX:%.*]] = getelementptr inbounds i8, ptr [[DST]], i64 50 359; CHECK-NEXT: store i16 [[A_SROA_6_SROA_0_0_COPYLOAD]], ptr [[A_SROA_6_0_DST_SROA_IDX]], align 1, !tbaa [[TBAA7]] 360; CHECK-NEXT: [[A_SROA_6_SROA_3_0_A_SROA_6_0_DST_SROA_IDX_SROA_IDX:%.*]] = getelementptr inbounds i8, ptr [[A_SROA_6_0_DST_SROA_IDX]], i64 2 361; CHECK-NEXT: store i8 [[A_SROA_6_SROA_3_0_COPYLOAD]], ptr [[A_SROA_6_SROA_3_0_A_SROA_6_0_DST_SROA_IDX_SROA_IDX]], align 1, !tbaa [[TBAA7]] 362; CHECK-NEXT: [[A_SROA_6_SROA_4_0_A_SROA_6_0_DST_SROA_IDX_SROA_IDX:%.*]] = getelementptr inbounds i8, ptr [[A_SROA_6_0_DST_SROA_IDX]], i64 3 363; CHECK-NEXT: call void @llvm.memcpy.p0.p0.i32(ptr align 1 [[A_SROA_6_SROA_4_0_A_SROA_6_0_DST_SROA_IDX_SROA_IDX]], ptr align 1 [[A_SROA_6_SROA_4]], i32 7, i1 false), !tbaa [[TBAA7]] 364; CHECK-NEXT: [[A_SROA_7_0_DST_SROA_IDX:%.*]] = getelementptr inbounds i8, ptr [[DST]], i64 60 365; CHECK-NEXT: call void @llvm.memcpy.p0.p0.i32(ptr align 1 [[A_SROA_7_0_DST_SROA_IDX]], ptr align 1 [[A_SROA_7]], i32 40, i1 false), !tbaa [[TBAA7]] 366; CHECK-NEXT: ret void 367; 368entry: 369 %a = alloca [100 x i8] 370 371 call void @llvm.memcpy.p0.p0.i32(ptr %a, ptr %src, i32 100, i1 false), !tbaa !0 372 373 %a.src.1 = getelementptr [100 x i8], ptr %a, i64 0, i64 20 374 %a.dst.1 = getelementptr [100 x i8], ptr %a, i64 0, i64 40 375 call void @llvm.memcpy.p0.p0.i32(ptr %a.dst.1, ptr %a.src.1, i32 10, i1 false), !tbaa !3 376 377 ; Clobber a single element of the array, this should be promotable, and be deleted. 378 %c = getelementptr [100 x i8], ptr %a, i64 0, i64 42 379 store i8 0, ptr %c 380 381 %a.src.2 = getelementptr [100 x i8], ptr %a, i64 0, i64 50 382 call void @llvm.memmove.p0.p0.i32(ptr %a.dst.1, ptr %a.src.2, i32 10, i1 false), !tbaa !5 383 384 call void @llvm.memcpy.p0.p0.i32(ptr %dst, ptr %a, i32 100, i1 false), !tbaa !7 385 386 ret void 387} 388 389declare void @llvm.memcpy.p0.p0.i32(ptr nocapture, ptr nocapture, i32, i1) nounwind 390declare void @llvm.memcpy.p1.p0.i32(ptr addrspace(1) nocapture, ptr nocapture, i32, i1) nounwind 391declare void @llvm.memmove.p0.p0.i32(ptr nocapture, ptr nocapture, i32, i1) nounwind 392declare void @llvm.memset.p0.i32(ptr nocapture, i8, i32, i1) nounwind 393 394define i16 @test5() { 395; CHECK-LABEL: @test5( 396; CHECK-NEXT: entry: 397; CHECK-NEXT: [[TMP0:%.*]] = bitcast float 0.000000e+00 to i32 398; CHECK-NEXT: [[A_SROA_0_2_EXTRACT_SHIFT:%.*]] = lshr i32 [[TMP0]], 16 399; CHECK-NEXT: [[A_SROA_0_2_EXTRACT_TRUNC:%.*]] = trunc i32 [[A_SROA_0_2_EXTRACT_SHIFT]] to i16 400; CHECK-NEXT: ret i16 [[A_SROA_0_2_EXTRACT_TRUNC]] 401; 402entry: 403 %a = alloca [4 x i8] 404 store float 0.0, ptr %a 405 %ptr = getelementptr [4 x i8], ptr %a, i32 0, i32 2 406 %val = load i16, ptr %ptr 407 ret i16 %val 408} 409 410define i16 @test5_multi_addrspace_access() { 411; CHECK-LABEL: @test5_multi_addrspace_access( 412; CHECK-NEXT: entry: 413; CHECK-NEXT: [[TMP0:%.*]] = bitcast float 0.000000e+00 to i32 414; CHECK-NEXT: [[A_SROA_0_2_EXTRACT_SHIFT:%.*]] = lshr i32 [[TMP0]], 16 415; CHECK-NEXT: [[A_SROA_0_2_EXTRACT_TRUNC:%.*]] = trunc i32 [[A_SROA_0_2_EXTRACT_SHIFT]] to i16 416; CHECK-NEXT: ret i16 [[A_SROA_0_2_EXTRACT_TRUNC]] 417; 418entry: 419 %a = alloca [4 x i8] 420 %fptr.as1 = addrspacecast ptr %a to ptr addrspace(1) 421 store float 0.0, ptr addrspace(1) %fptr.as1 422 %ptr = getelementptr [4 x i8], ptr %a, i32 0, i32 2 423 %val = load i16, ptr %ptr 424 ret i16 %val 425} 426 427define i32 @test6() { 428; CHECK-LABEL: @test6( 429; CHECK-NEXT: entry: 430; CHECK-NEXT: [[A_SROA_0:%.*]] = alloca i32, align 4 431; CHECK-NEXT: store volatile i32 707406378, ptr [[A_SROA_0]], align 4 432; CHECK-NEXT: [[A_SROA_0_0_A_SROA_0_0_VAL:%.*]] = load i32, ptr [[A_SROA_0]], align 4 433; CHECK-NEXT: ret i32 [[A_SROA_0_0_A_SROA_0_0_VAL]] 434; 435entry: 436 %a = alloca [4 x i8] 437 call void @llvm.memset.p0.i32(ptr %a, i8 42, i32 4, i1 true) 438 %val = load i32, ptr %a 439 ret i32 %val 440} 441 442define void @test7(ptr %src, ptr %dst) { 443; CHECK-LABEL: @test7( 444; CHECK-NEXT: entry: 445; CHECK-NEXT: [[A_SROA_0:%.*]] = alloca i32, align 4 446; CHECK-NEXT: [[A_SROA_0_0_COPYLOAD:%.*]] = load volatile i32, ptr [[SRC:%.*]], align 1, !tbaa [[TBAA0]] 447; CHECK-NEXT: store volatile i32 [[A_SROA_0_0_COPYLOAD]], ptr [[A_SROA_0]], align 4, !tbaa [[TBAA0]] 448; CHECK-NEXT: [[A_SROA_0_0_A_SROA_0_0_COPYLOAD1:%.*]] = load volatile i32, ptr [[A_SROA_0]], align 4, !tbaa [[TBAA3]] 449; CHECK-NEXT: store volatile i32 [[A_SROA_0_0_A_SROA_0_0_COPYLOAD1]], ptr [[DST:%.*]], align 1, !tbaa [[TBAA3]] 450; CHECK-NEXT: ret void 451; 452entry: 453 %a = alloca [4 x i8] 454 call void @llvm.memcpy.p0.p0.i32(ptr %a, ptr %src, i32 4, i1 true), !tbaa !0 455 call void @llvm.memcpy.p0.p0.i32(ptr %dst, ptr %a, i32 4, i1 true), !tbaa !3 456 ret void 457} 458 459 460%S1 = type { i32, i32, [16 x i8] } 461%S2 = type { ptr, ptr } 462 463define %S2 @test8(ptr %arg) { 464; CHECK-LABEL: @test8( 465; CHECK-NEXT: entry: 466; CHECK-NEXT: [[S2_NEXT_PTR:%.*]] = getelementptr [[S2:%.*]], ptr [[ARG:%.*]], i64 0, i32 1 467; CHECK-NEXT: [[S2_NEXT:%.*]] = load ptr, ptr [[S2_NEXT_PTR]], align 8, !tbaa [[TBAA0]] 468; CHECK-NEXT: [[S2_NEXT_S1:%.*]] = load ptr, ptr [[S2_NEXT]], align 8, !tbaa [[TBAA3]] 469; CHECK-NEXT: [[S2_NEXT_NEXT_PTR:%.*]] = getelementptr [[S2]], ptr [[S2_NEXT]], i64 0, i32 1 470; CHECK-NEXT: [[S2_NEXT_NEXT:%.*]] = load ptr, ptr [[S2_NEXT_NEXT_PTR]], align 8, !tbaa [[TBAA7]] 471; CHECK-NEXT: [[RESULT1:%.*]] = insertvalue [[S2]] poison, ptr [[S2_NEXT_S1]], 0 472; CHECK-NEXT: [[RESULT2:%.*]] = insertvalue [[S2]] [[RESULT1]], ptr [[S2_NEXT_NEXT]], 1 473; CHECK-NEXT: ret [[S2]] [[RESULT2]] 474; 475entry: 476 %new = alloca %S2 477 478 %s2.next.ptr = getelementptr %S2, ptr %arg, i64 0, i32 1 479 %s2.next = load ptr, ptr %s2.next.ptr, !tbaa !0 480 481 %s2.next.s1 = load ptr, ptr %s2.next, !tbaa !3 482 store ptr %s2.next.s1, ptr %new, !tbaa !5 483 %s2.next.next.ptr = getelementptr %S2, ptr %s2.next, i64 0, i32 1 484 %s2.next.next = load ptr, ptr %s2.next.next.ptr, !tbaa !7 485 %new.next.ptr = getelementptr %S2, ptr %new, i64 0, i32 1 486 store ptr %s2.next.next, ptr %new.next.ptr, !tbaa !9 487 488 %new.s1 = load ptr, ptr %new 489 %result1 = insertvalue %S2 poison, ptr %new.s1, 0 490 %new.next = load ptr, ptr %new.next.ptr 491 %result2 = insertvalue %S2 %result1, ptr %new.next, 1 492 ret %S2 %result2 493} 494 495define i64 @test9() { 496; Ensure we can handle loads off the end of an alloca even when wrapped in 497; weird bit casts and types. This is valid IR due to the alignment and masking 498; off the bits past the end of the alloca. 499; 500; 501; CHECK-LABEL: @test9( 502; CHECK-NEXT: entry: 503; CHECK-NEXT: [[A_SROA_3_0_INSERT_EXT:%.*]] = zext i8 26 to i64 504; CHECK-NEXT: [[A_SROA_3_0_INSERT_SHIFT:%.*]] = shl i64 [[A_SROA_3_0_INSERT_EXT]], 16 505; CHECK-NEXT: [[A_SROA_3_0_INSERT_MASK:%.*]] = and i64 undef, -16711681 506; CHECK-NEXT: [[A_SROA_3_0_INSERT_INSERT:%.*]] = or i64 [[A_SROA_3_0_INSERT_MASK]], [[A_SROA_3_0_INSERT_SHIFT]] 507; CHECK-NEXT: [[A_SROA_2_0_INSERT_EXT:%.*]] = zext i8 0 to i64 508; CHECK-NEXT: [[A_SROA_2_0_INSERT_SHIFT:%.*]] = shl i64 [[A_SROA_2_0_INSERT_EXT]], 8 509; CHECK-NEXT: [[A_SROA_2_0_INSERT_MASK:%.*]] = and i64 [[A_SROA_3_0_INSERT_INSERT]], -65281 510; CHECK-NEXT: [[A_SROA_2_0_INSERT_INSERT:%.*]] = or i64 [[A_SROA_2_0_INSERT_MASK]], [[A_SROA_2_0_INSERT_SHIFT]] 511; CHECK-NEXT: [[A_SROA_0_0_INSERT_EXT:%.*]] = zext i8 0 to i64 512; CHECK-NEXT: [[A_SROA_0_0_INSERT_MASK:%.*]] = and i64 [[A_SROA_2_0_INSERT_INSERT]], -256 513; CHECK-NEXT: [[A_SROA_0_0_INSERT_INSERT:%.*]] = or i64 [[A_SROA_0_0_INSERT_MASK]], [[A_SROA_0_0_INSERT_EXT]] 514; CHECK-NEXT: [[RESULT:%.*]] = and i64 [[A_SROA_0_0_INSERT_INSERT]], 16777215 515; CHECK-NEXT: ret i64 [[RESULT]] 516; 517entry: 518 %a = alloca { [3 x i8] }, align 8 519 store i8 0, ptr %a, align 1 520 %gep2 = getelementptr inbounds { [3 x i8] }, ptr %a, i32 0, i32 0, i32 1 521 store i8 0, ptr %gep2, align 1 522 %gep3 = getelementptr inbounds { [3 x i8] }, ptr %a, i32 0, i32 0, i32 2 523 store i8 26, ptr %gep3, align 1 524 %load = load i64, ptr %a 525 %result = and i64 %load, 16777215 526 ret i64 %result 527} 528 529define ptr @test10() { 530; CHECK-LABEL: @test10( 531; CHECK-NEXT: entry: 532; CHECK-NEXT: [[TMP0:%.*]] = ptrtoint ptr null to i64 533; CHECK-NEXT: ret ptr null 534; 535entry: 536 %a = alloca [8 x i8] 537 call void @llvm.memset.p0.i32(ptr %a, i8 0, i32 8, i1 false) 538 %s2ptr = load ptr, ptr %a 539 ret ptr %s2ptr 540} 541 542define i32 @test11(i1 %c1) { 543; CHECK-LABEL: @test11( 544; CHECK-NEXT: entry: 545; CHECK-NEXT: br i1 [[C1:%.*]], label [[GOOD:%.*]], label [[BAD:%.*]] 546; CHECK: good: 547; CHECK-NEXT: ret i32 0 548; CHECK: bad: 549; CHECK-NEXT: ret i32 poison 550; 551entry: 552 %X = alloca i32 553 br i1 %c1, label %good, label %bad 554 555good: 556 store i32 0, ptr %X 557 %Z = load i32, ptr %X 558 ret i32 %Z 559 560bad: 561 %Y2 = getelementptr i32, ptr %X, i64 1 562 store i32 0, ptr %Y2 563 %Z2 = load i32, ptr %Y2 564 ret i32 %Z2 565} 566 567define i8 @test12() { 568; We fully promote these to the i24 load or store size, resulting in just masks 569; and other operations that instcombine will fold, but no alloca. 570; 571; 572; CHECK-LABEL: @test12( 573; CHECK-NEXT: entry: 574; CHECK-NEXT: [[A_SROA_3_0_INSERT_EXT:%.*]] = zext i8 0 to i24 575; CHECK-NEXT: [[A_SROA_3_0_INSERT_SHIFT:%.*]] = shl i24 [[A_SROA_3_0_INSERT_EXT]], 16 576; CHECK-NEXT: [[A_SROA_3_0_INSERT_MASK:%.*]] = and i24 undef, 65535 577; CHECK-NEXT: [[A_SROA_3_0_INSERT_INSERT:%.*]] = or i24 [[A_SROA_3_0_INSERT_MASK]], [[A_SROA_3_0_INSERT_SHIFT]] 578; CHECK-NEXT: [[A_SROA_2_0_INSERT_EXT:%.*]] = zext i8 0 to i24 579; CHECK-NEXT: [[A_SROA_2_0_INSERT_SHIFT:%.*]] = shl i24 [[A_SROA_2_0_INSERT_EXT]], 8 580; CHECK-NEXT: [[A_SROA_2_0_INSERT_MASK:%.*]] = and i24 [[A_SROA_3_0_INSERT_INSERT]], -65281 581; CHECK-NEXT: [[A_SROA_2_0_INSERT_INSERT:%.*]] = or i24 [[A_SROA_2_0_INSERT_MASK]], [[A_SROA_2_0_INSERT_SHIFT]] 582; CHECK-NEXT: [[A_SROA_0_0_INSERT_EXT:%.*]] = zext i8 0 to i24 583; CHECK-NEXT: [[A_SROA_0_0_INSERT_MASK:%.*]] = and i24 [[A_SROA_2_0_INSERT_INSERT]], -256 584; CHECK-NEXT: [[A_SROA_0_0_INSERT_INSERT:%.*]] = or i24 [[A_SROA_0_0_INSERT_MASK]], [[A_SROA_0_0_INSERT_EXT]] 585; CHECK-NEXT: [[B_SROA_0_0_EXTRACT_TRUNC:%.*]] = trunc i24 [[A_SROA_0_0_INSERT_INSERT]] to i8 586; CHECK-NEXT: [[B_SROA_2_0_EXTRACT_SHIFT:%.*]] = lshr i24 [[A_SROA_0_0_INSERT_INSERT]], 8 587; CHECK-NEXT: [[B_SROA_2_0_EXTRACT_TRUNC:%.*]] = trunc i24 [[B_SROA_2_0_EXTRACT_SHIFT]] to i8 588; CHECK-NEXT: [[B_SROA_3_0_EXTRACT_SHIFT:%.*]] = lshr i24 [[A_SROA_0_0_INSERT_INSERT]], 16 589; CHECK-NEXT: [[B_SROA_3_0_EXTRACT_TRUNC:%.*]] = trunc i24 [[B_SROA_3_0_EXTRACT_SHIFT]] to i8 590; CHECK-NEXT: [[BSUM0:%.*]] = add i8 [[B_SROA_0_0_EXTRACT_TRUNC]], [[B_SROA_2_0_EXTRACT_TRUNC]] 591; CHECK-NEXT: [[BSUM1:%.*]] = add i8 [[BSUM0]], [[B_SROA_3_0_EXTRACT_TRUNC]] 592; CHECK-NEXT: ret i8 [[BSUM1]] 593; 594entry: 595 %a = alloca [3 x i8] 596 %b = alloca [3 x i8] 597 598 store i8 0, ptr %a 599 %a1ptr = getelementptr [3 x i8], ptr %a, i64 0, i32 1 600 store i8 0, ptr %a1ptr 601 %a2ptr = getelementptr [3 x i8], ptr %a, i64 0, i32 2 602 store i8 0, ptr %a2ptr 603 %ai = load i24, ptr %a 604 605 store i24 %ai, ptr %b 606 %b0 = load i8, ptr %b 607 %b1ptr = getelementptr [3 x i8], ptr %b, i64 0, i32 1 608 %b1 = load i8, ptr %b1ptr 609 %b2ptr = getelementptr [3 x i8], ptr %b, i64 0, i32 2 610 %b2 = load i8, ptr %b2ptr 611 612 %bsum0 = add i8 %b0, %b1 613 %bsum1 = add i8 %bsum0, %b2 614 ret i8 %bsum1 615} 616 617define i32 @test13() { 618; Ensure we don't crash and handle undefined loads that straddle the end of the 619; allocation. 620; 621; CHECK-LABEL: @test13( 622; CHECK-NEXT: entry: 623; CHECK-NEXT: [[A_SROA_2_2_LOAD_EXT:%.*]] = zext i8 0 to i16 624; CHECK-NEXT: [[RET:%.*]] = zext i16 [[A_SROA_2_2_LOAD_EXT]] to i32 625; CHECK-NEXT: ret i32 [[RET]] 626; 627entry: 628 %a = alloca [3 x i8], align 2 629 store i8 0, ptr %a 630 %b1ptr = getelementptr [3 x i8], ptr %a, i64 0, i32 1 631 store i8 0, ptr %b1ptr 632 %b2ptr = getelementptr [3 x i8], ptr %a, i64 0, i32 2 633 store i8 0, ptr %b2ptr 634 %iptrgep = getelementptr i16, ptr %a, i64 1 635 %i = load i16, ptr %iptrgep 636 %ret = zext i16 %i to i32 637 ret i32 %ret 638} 639 640%test14.struct = type { [3 x i32] } 641 642define void @test14(...) nounwind uwtable { 643; This is a strange case where we split allocas into promotable partitions, but 644; also gain enough data to prove they must be dead allocas due to GEPs that walk 645; across two adjacent allocas. Test that we don't try to promote or otherwise 646; do bad things to these dead allocas, they should just be removed. 647; 648; CHECK-LABEL: @test14( 649; CHECK-NEXT: entry: 650; CHECK-NEXT: ret void 651; 652entry: 653 %a = alloca %test14.struct 654 %p = alloca ptr 655 %0 = getelementptr i8, ptr %a, i64 12 656 %1 = load i32, ptr %a, align 4 657 store i32 %1, ptr %0, align 4 658 %2 = getelementptr inbounds i32, ptr %0, i32 1 659 %3 = getelementptr inbounds i32, ptr %a, i32 1 660 %4 = load i32, ptr %3, align 4 661 store i32 %4, ptr %2, align 4 662 %5 = getelementptr inbounds i32, ptr %0, i32 2 663 %6 = getelementptr inbounds i32, ptr %a, i32 2 664 %7 = load i32, ptr %6, align 4 665 store i32 %7, ptr %5, align 4 666 ret void 667} 668 669define i32 @test15(i1 %flag) nounwind uwtable { 670; Ensure that when there are dead instructions using an alloca that are not 671; loads or stores we still delete them during partitioning and rewriting. 672; Otherwise we'll go to promote them while thy still have unpromotable uses. 673; 674; CHECK-LABEL: @test15( 675; CHECK-NEXT: entry: 676; CHECK-NEXT: br label [[LOOP:%.*]] 677; CHECK: loop: 678; CHECK-NEXT: br label [[LOOP]] 679; 680entry: 681 %l0 = alloca i64 682 %l1 = alloca i64 683 %l2 = alloca i64 684 %l3 = alloca i64 685 br label %loop 686 687loop: 688 %dead3 = phi ptr [ %gep3, %loop ], [ null, %entry ] 689 690 store i64 1879048192, ptr %l0, align 8 691 %gep0 = getelementptr i8, ptr %l0, i64 3 692 693 store i64 1879048192, ptr %l1, align 8 694 %gep1 = getelementptr i8, ptr %l1, i64 3 695 %dead1 = getelementptr i8, ptr %gep1, i64 1 696 697 store i64 1879048192, ptr %l2, align 8 698 %gep2.1 = getelementptr i8, ptr %l2, i64 1 699 %gep2.2 = getelementptr i8, ptr %l2, i64 3 700 ; Note that this select should get visited multiple times due to using two 701 ; different GEPs off the same alloca. We should only delete it once. 702 %dead2 = select i1 %flag, ptr %gep2.1, ptr %gep2.2 703 704 store i64 1879048192, ptr %l3, align 8 705 %gep3 = getelementptr i8, ptr %l3, i64 3 706 707 br label %loop 708} 709 710define void @test16(ptr %src, ptr %dst) { 711; Ensure that we can promote an alloca of [3 x i8] to an i24 SSA value. 712; 713; CHECK-LABEL: @test16( 714; CHECK-NEXT: entry: 715; CHECK-NEXT: [[A_SROA_0_0_COPYLOAD:%.*]] = load i24, ptr [[SRC:%.*]], align 1, !tbaa [[TBAA0]] 716; CHECK-NEXT: store i24 0, ptr [[DST:%.*]], align 1, !tbaa [[TBAA5]] 717; CHECK-NEXT: ret void 718; 719entry: 720 %a = alloca [3 x i8] 721 call void @llvm.memcpy.p0.p0.i32(ptr %a, ptr %src, i32 4, i1 false), !tbaa !0 722 store i24 0, ptr %a, !tbaa !3 723 call void @llvm.memcpy.p0.p0.i32(ptr %dst, ptr %a, i32 4, i1 false), !tbaa !5 724 ret void 725} 726 727define void @test17(ptr %src, ptr %dst) { 728; Ensure that we can rewrite unpromotable memcpys which extend past the end of 729; the alloca. 730; 731; CHECK-LABEL: @test17( 732; CHECK-NEXT: entry: 733; CHECK-NEXT: [[A:%.*]] = alloca [3 x i8], align 1 734; CHECK-NEXT: call void @llvm.memcpy.p0.p0.i32(ptr [[A]], ptr [[SRC:%.*]], i32 4, i1 true), !tbaa [[TBAA0]] 735; CHECK-NEXT: call void @llvm.memcpy.p0.p0.i32(ptr [[DST:%.*]], ptr [[A]], i32 4, i1 true), !tbaa [[TBAA3]] 736; CHECK-NEXT: ret void 737; 738entry: 739 %a = alloca [3 x i8] 740 call void @llvm.memcpy.p0.p0.i32(ptr %a, ptr %src, i32 4, i1 true), !tbaa !0 741 call void @llvm.memcpy.p0.p0.i32(ptr %dst, ptr %a, i32 4, i1 true), !tbaa !3 742 ret void 743} 744 745define void @test18(ptr %src, ptr %dst, i32 %size) { 746; Preserve transfer intrinsics with a variable size, even if they overlap with 747; fixed size operations. Further, continue to split and promote allocas preceding 748; the variable sized intrinsic. 749; 750; CHECK-LABEL: @test18( 751; CHECK-NEXT: entry: 752; CHECK-NEXT: [[A_SROA_33:%.*]] = alloca [34 x i8], align 1 753; CHECK-NEXT: [[A_SROA_0_0_COPYLOAD:%.*]] = load i32, ptr [[SRC:%.*]], align 1, !tbaa [[TBAA0]] 754; CHECK-NEXT: [[A_SROA_3_0_SRC_SROA_IDX:%.*]] = getelementptr inbounds i8, ptr [[SRC]], i64 4 755; CHECK-NEXT: [[A_SROA_3_0_COPYLOAD:%.*]] = load i32, ptr [[A_SROA_3_0_SRC_SROA_IDX]], align 1, !tbaa [[TBAA0]] 756; CHECK-NEXT: call void @llvm.memcpy.p0.p0.i32(ptr align 1 [[A_SROA_33]], ptr [[SRC]], i32 [[SIZE:%.*]], i1 false), !tbaa [[TBAA3]] 757; CHECK-NEXT: call void @llvm.memset.p0.i32(ptr align 1 [[A_SROA_33]], i8 42, i32 [[SIZE]], i1 false), !tbaa [[TBAA5]] 758; CHECK-NEXT: store i32 42, ptr [[DST:%.*]], align 1, !tbaa [[TBAA9]] 759; CHECK-NEXT: [[A_SROA_3_0_DST_SROA_IDX:%.*]] = getelementptr inbounds i8, ptr [[DST]], i64 4 760; CHECK-NEXT: store i32 [[A_SROA_3_0_COPYLOAD]], ptr [[A_SROA_3_0_DST_SROA_IDX]], align 1, !tbaa [[TBAA9]] 761; CHECK-NEXT: call void @llvm.memcpy.p0.p0.i32(ptr [[DST]], ptr align 1 [[A_SROA_33]], i32 [[SIZE]], i1 false), !tbaa [[TBAA11]] 762; CHECK-NEXT: ret void 763; 764entry: 765 %a = alloca [42 x i8] 766 call void @llvm.memcpy.p0.p0.i32(ptr %a, ptr %src, i32 8, i1 false), !tbaa !0 767 %ptr2 = getelementptr [42 x i8], ptr %a, i32 0, i32 8 768 call void @llvm.memcpy.p0.p0.i32(ptr %ptr2, ptr %src, i32 %size, i1 false), !tbaa !3 769 call void @llvm.memset.p0.i32(ptr %ptr2, i8 42, i32 %size, i1 false), !tbaa !5 770 store i32 42, ptr %a, !tbaa !7 771 call void @llvm.memcpy.p0.p0.i32(ptr %dst, ptr %a, i32 8, i1 false), !tbaa !9 772 call void @llvm.memcpy.p0.p0.i32(ptr %dst, ptr %ptr2, i32 %size, i1 false), !tbaa !11 773 ret void 774} 775 776%opaque = type opaque 777 778define i64 @test19(ptr %x) { 779; This input will cause us to try to compute a natural GEP when rewriting 780; pointers in such a way that we try to GEP through the opaque type. Previously, 781; a check for an unsized type was missing and this crashed. Ensure it behaves 782; reasonably now. 783; 784; CHECK-LABEL: @test19( 785; CHECK-NEXT: entry: 786; CHECK-NEXT: [[A_SROA_0_0_COPYLOAD:%.*]] = load i64, ptr [[X:%.*]], align 1 787; CHECK-NEXT: [[A_SROA_2_0_X_SROA_IDX:%.*]] = getelementptr inbounds i8, ptr [[X]], i64 8 788; CHECK-NEXT: [[A_SROA_2_0_COPYLOAD:%.*]] = load ptr, ptr [[A_SROA_2_0_X_SROA_IDX]], align 1 789; CHECK-NEXT: ret i64 [[A_SROA_0_0_COPYLOAD]] 790; 791entry: 792 %a = alloca { i64, ptr } 793 call void @llvm.memcpy.p0.p0.i32(ptr %a, ptr %x, i32 16, i1 false) 794 %gep = getelementptr inbounds { i64, ptr }, ptr %a, i32 0, i32 0 795 %val = load i64, ptr %gep 796 ret i64 %val 797} 798 799declare void @llvm.memcpy.p0.p1.i32(ptr nocapture, ptr addrspace(1) nocapture, i32, i32, i1) nounwind 800 801define i64 @test19_addrspacecast(ptr %x) { 802; This input will cause us to try to compute a natural GEP when rewriting 803; pointers in such a way that we try to GEP through the opaque type. Previously, 804; a check for an unsized type was missing and this crashed. Ensure it behaves 805; reasonably now. 806; 807; CHECK-LABEL: @test19_addrspacecast( 808; CHECK-NEXT: entry: 809; CHECK-NEXT: [[CAST1:%.*]] = addrspacecast ptr [[X:%.*]] to ptr addrspace(1) 810; CHECK-NEXT: [[A_SROA_0_0_COPYLOAD:%.*]] = load i64, ptr addrspace(1) [[CAST1]], align 1 811; CHECK-NEXT: [[A_SROA_2_0_CAST1_SROA_IDX:%.*]] = getelementptr inbounds i8, ptr addrspace(1) [[CAST1]], i16 8 812; CHECK-NEXT: [[A_SROA_2_0_COPYLOAD:%.*]] = load ptr, ptr addrspace(1) [[A_SROA_2_0_CAST1_SROA_IDX]], align 1 813; CHECK-NEXT: ret i64 [[A_SROA_0_0_COPYLOAD]] 814; 815entry: 816 %a = alloca { i64, ptr } 817 %cast1 = addrspacecast ptr %x to ptr addrspace(1) 818 call void @llvm.memcpy.p0.p1.i32(ptr %a, ptr addrspace(1) %cast1, i32 16, i32 1, i1 false) 819 %gep = getelementptr inbounds { i64, ptr }, ptr %a, i32 0, i32 0 820 %val = load i64, ptr %gep 821 ret i64 %val 822} 823 824define i32 @test20() { 825; Ensure we can track negative offsets (before the beginning of the alloca) and 826; negative relative offsets from offsets starting past the end of the alloca. 827; 828; CHECK-LABEL: @test20( 829; CHECK-NEXT: entry: 830; CHECK-NEXT: [[SUM1:%.*]] = add i32 1, 2 831; CHECK-NEXT: [[SUM2:%.*]] = add i32 [[SUM1]], 3 832; CHECK-NEXT: ret i32 [[SUM2]] 833; 834entry: 835 %a = alloca [3 x i32] 836 store i32 1, ptr %a 837 %gep2.1 = getelementptr [3 x i32], ptr %a, i32 0, i32 -2 838 %gep2.2 = getelementptr i32, ptr %gep2.1, i32 3 839 store i32 2, ptr %gep2.2 840 %gep3.1 = getelementptr [3 x i32], ptr %a, i32 0, i32 14 841 %gep3.2 = getelementptr i32, ptr %gep3.1, i32 -12 842 store i32 3, ptr %gep3.2 843 844 %load1 = load i32, ptr %a 845 %load2 = load i32, ptr %gep2.2 846 %load3 = load i32, ptr %gep3.2 847 %sum1 = add i32 %load1, %load2 848 %sum2 = add i32 %sum1, %load3 849 ret i32 %sum2 850} 851 852declare void @llvm.memset.p0.i64(ptr nocapture, i8, i64, i1) nounwind 853 854define i8 @test21() { 855; Test allocations and offsets which border on overflow of the int64_t used 856; internally. This is really awkward to really test as LLVM doesn't really 857; support such extreme constructs cleanly. 858; 859; CHECK-LABEL: @test21( 860; CHECK-NEXT: entry: 861; CHECK-NEXT: [[RESULT:%.*]] = or i8 -1, -1 862; CHECK-NEXT: ret i8 [[RESULT]] 863; 864entry: 865 %a = alloca [2305843009213693951 x i8] 866 %gep0 = getelementptr [2305843009213693951 x i8], ptr %a, i64 0, i64 2305843009213693949 867 store i8 255, ptr %gep0 868 %gep1 = getelementptr [2305843009213693951 x i8], ptr %a, i64 0, i64 -9223372036854775807 869 %gep2 = getelementptr i8, ptr %gep1, i64 -1 870 call void @llvm.memset.p0.i64(ptr %gep2, i8 0, i64 18446744073709551615, i1 false) 871 %gep3 = getelementptr i8, ptr %gep1, i64 9223372036854775807 872 %gep4 = getelementptr i8, ptr %gep3, i64 9223372036854775807 873 %gep5 = getelementptr i8, ptr %gep4, i64 -6917529027641081857 874 store i8 255, ptr %gep5 875 store i32 0, ptr %gep4 876 %load = load i8, ptr %gep0 877 %gep6 = getelementptr i8, ptr %gep0, i32 1 878 %load2 = load i8, ptr %gep6 879 %result = or i8 %load, %load2 880 ret i8 %result 881} 882 883%PR13916.struct = type { i8 } 884 885define void @PR13916.1() { 886; Ensure that we handle overlapping memcpy intrinsics correctly, especially in 887; the case where there is a directly identical value for both source and dest. 888; 889; CHECK-LABEL: @PR13916.1( 890; CHECK-NEXT: entry: 891; CHECK-NEXT: ret void 892; 893entry: 894 %a = alloca i8 895 call void @llvm.memcpy.p0.p0.i32(ptr %a, ptr %a, i32 1, i1 false) 896 %tmp2 = load i8, ptr %a 897 ret void 898} 899 900define void @PR13916.2(i1 %c1) { 901; Check whether we continue to handle them correctly when they start off with 902; different pointer value chains, but during rewriting we coalesce them into the 903; same value. 904; 905; CHECK-LABEL: @PR13916.2( 906; CHECK-NEXT: entry: 907; CHECK-NEXT: br i1 [[C1:%.*]], label [[IF_THEN:%.*]], label [[IF_END:%.*]] 908; CHECK: if.then: 909; CHECK-NEXT: br label [[IF_END]] 910; CHECK: if.end: 911; CHECK-NEXT: ret void 912; 913entry: 914 %a = alloca %PR13916.struct, align 1 915 br i1 %c1, label %if.then, label %if.end 916 917if.then: 918 call void @llvm.memcpy.p0.p0.i32(ptr %a, ptr %a, i32 1, i1 false) 919 br label %if.end 920 921if.end: 922 %tmp2 = load i8, ptr %a 923 ret void 924} 925 926define void @PR13990(i1 %c1, i1 %c2, i1 %c3, i1 %c4, ptr %ptr) { 927; Ensure we can handle cases where processing one alloca causes the other 928; alloca to become dead and get deleted. This might crash or fail under 929; Valgrind if we regress. 930; 931; CHECK-LABEL: @PR13990( 932; CHECK-NEXT: entry: 933; CHECK-NEXT: br i1 [[C1:%.*]], label [[BB1:%.*]], label [[BB2:%.*]] 934; CHECK: bb1: 935; CHECK-NEXT: br i1 [[C2:%.*]], label [[BB2]], label [[BB3:%.*]] 936; CHECK: bb2: 937; CHECK-NEXT: br i1 [[C4:%.*]], label [[BB3]], label [[BB4:%.*]] 938; CHECK: bb3: 939; CHECK-NEXT: unreachable 940; CHECK: bb4: 941; CHECK-NEXT: unreachable 942; 943entry: 944 %tmp1 = alloca ptr 945 %tmp2 = alloca ptr 946 br i1 %c1, label %bb1, label %bb2 947 948bb1: 949 store ptr %ptr, ptr %tmp2 950 br i1 %c2, label %bb2, label %bb3 951 952bb2: 953 %tmp50 = select i1 %c3, ptr %tmp2, ptr %tmp1 954 br i1 %c4, label %bb3, label %bb4 955 956bb3: 957 unreachable 958 959bb4: 960 unreachable 961} 962 963define double @PR13969(double %x) { 964; Check that we detect when promotion will un-escape an alloca and iterate to 965; re-try running SROA over that alloca. Without that, the two allocas that are 966; stored into a dead alloca don't get rewritten and promoted. 967; 968; CHECK-LABEL: @PR13969( 969; CHECK-NEXT: entry: 970; CHECK-NEXT: ret double [[X:%.*]] 971; 972entry: 973 %a = alloca double 974 %b = alloca ptr 975 %c = alloca double 976 977 store double %x, ptr %a 978 store ptr %c, ptr %b 979 store ptr %a, ptr %b 980 store double %x, ptr %c 981 %ret = load double, ptr %a 982 983 ret double %ret 984} 985 986%PR14034.struct = type { { {} }, i32, %PR14034.list } 987%PR14034.list = type { ptr, ptr } 988 989define void @PR14034(ptr %ptr, ptr %ptr2) { 990; This test case tries to form GEPs into the empty leading struct members, and 991; subsequently crashed (under valgrind) before we fixed the PR. The important 992; thing is to handle empty structs gracefully. 993; 994; CHECK-LABEL: @PR14034( 995; CHECK-NEXT: entry: 996; CHECK-NEXT: [[A_SROA_0:%.*]] = alloca [12 x i8], align 8 997; CHECK-NEXT: call void @llvm.memcpy.p0.p0.i32(ptr align 1 [[PTR2:%.*]], ptr align 8 [[A_SROA_0]], i32 12, i1 false) 998; CHECK-NEXT: ret void 999; 1000entry: 1001 %a = alloca %PR14034.struct 1002 %list = getelementptr %PR14034.struct, ptr %a, i32 0, i32 2 1003 %prev = getelementptr %PR14034.list, ptr %list, i32 0, i32 1 1004 store ptr %ptr, ptr %prev 1005 call void @llvm.memcpy.p0.p0.i32(ptr %ptr2, ptr %a, i32 12, i1 false) 1006 ret void 1007} 1008 1009define i32 @test22(i32 %x) { 1010; Test that SROA and promotion is not confused by a grab bax mixture of pointer 1011; types involving wrapper aggregates and zero-length aggregate members. 1012; 1013; CHECK-LABEL: @test22( 1014; CHECK-NEXT: entry: 1015; CHECK-NEXT: [[WRAP1:%.*]] = insertvalue [1 x { i32 }] poison, i32 [[X:%.*]], 0, 0 1016; CHECK-NEXT: [[WRAP1_FCA_0_0_EXTRACT:%.*]] = extractvalue [1 x { i32 }] [[WRAP1]], 0, 0 1017; CHECK-NEXT: [[TMP0:%.*]] = bitcast i32 [[WRAP1_FCA_0_0_EXTRACT]] to float 1018; CHECK-NEXT: [[LOAD1_FCA_0_0_0_INSERT:%.*]] = insertvalue { [1 x { float }] } poison, float [[TMP0]], 0, 0, 0 1019; CHECK-NEXT: [[UNWRAP1:%.*]] = extractvalue { [1 x { float }] } [[LOAD1_FCA_0_0_0_INSERT]], 0, 0 1020; CHECK-NEXT: [[WRAP2:%.*]] = insertvalue { {}, { float }, [0 x i8] } poison, { float } [[UNWRAP1]], 1 1021; CHECK-NEXT: [[WRAP2_FCA_1_0_EXTRACT:%.*]] = extractvalue { {}, { float }, [0 x i8] } [[WRAP2]], 1, 0 1022; CHECK-NEXT: [[TMP1:%.*]] = bitcast float [[WRAP2_FCA_1_0_EXTRACT]] to <4 x i8> 1023; CHECK-NEXT: [[VALCAST1:%.*]] = bitcast <4 x i8> [[TMP1]] to i32 1024; CHECK-NEXT: [[WRAP3:%.*]] = insertvalue [1 x [1 x i32]] poison, i32 [[VALCAST1]], 0, 0 1025; CHECK-NEXT: [[WRAP4:%.*]] = insertvalue { [1 x [1 x i32]], {} } poison, [1 x [1 x i32]] [[WRAP3]], 0 1026; CHECK-NEXT: [[WRAP4_FCA_0_0_0_EXTRACT:%.*]] = extractvalue { [1 x [1 x i32]], {} } [[WRAP4]], 0, 0, 0 1027; CHECK-NEXT: [[TMP2:%.*]] = bitcast i32 [[WRAP4_FCA_0_0_0_EXTRACT]] to <4 x i8> 1028; CHECK-NEXT: [[TMP3:%.*]] = bitcast <4 x i8> [[TMP2]] to float 1029; CHECK-NEXT: [[LOAD4_FCA_1_INSERT:%.*]] = insertvalue { {}, float, {} } poison, float [[TMP3]], 1 1030; CHECK-NEXT: [[UNWRAP2:%.*]] = extractvalue { {}, float, {} } [[LOAD4_FCA_1_INSERT]], 1 1031; CHECK-NEXT: [[VALCAST2:%.*]] = bitcast float [[UNWRAP2]] to i32 1032; CHECK-NEXT: ret i32 [[VALCAST2]] 1033; 1034entry: 1035 %a1 = alloca { { [1 x { i32 }] } } 1036 %a2 = alloca { {}, { float }, [0 x i8] } 1037 %a3 = alloca { [0 x i8], { [0 x double], [1 x [1 x <4 x i8>]], {} }, { { {} } } } 1038 1039 %wrap1 = insertvalue [1 x { i32 }] poison, i32 %x, 0, 0 1040 store [1 x { i32 }] %wrap1, ptr %a1 1041 1042 %load1 = load { [1 x { float }] }, ptr %a1 1043 %unwrap1 = extractvalue { [1 x { float }] } %load1, 0, 0 1044 1045 %wrap2 = insertvalue { {}, { float }, [0 x i8] } poison, { float } %unwrap1, 1 1046 store { {}, { float }, [0 x i8] } %wrap2, ptr %a2 1047 1048 %gep3 = getelementptr { {}, { float }, [0 x i8] }, ptr %a2, i32 0, i32 1, i32 0 1049 %load3 = load <4 x i8>, ptr %gep3 1050 %valcast1 = bitcast <4 x i8> %load3 to i32 1051 1052 %wrap3 = insertvalue [1 x [1 x i32]] poison, i32 %valcast1, 0, 0 1053 %wrap4 = insertvalue { [1 x [1 x i32]], {} } poison, [1 x [1 x i32]] %wrap3, 0 1054 %gep4 = getelementptr { [0 x i8], { [0 x double], [1 x [1 x <4 x i8>]], {} }, { { {} } } }, ptr %a3, i32 0, i32 1 1055 store { [1 x [1 x i32]], {} } %wrap4, ptr %gep4 1056 1057 %gep5 = getelementptr { [0 x i8], { [0 x double], [1 x [1 x <4 x i8>]], {} }, { { {} } } }, ptr %a3, i32 0, i32 1, i32 1, i32 0 1058 %load4 = load { {}, float, {} }, ptr %gep5 1059 %unwrap2 = extractvalue { {}, float, {} } %load4, 1 1060 %valcast2 = bitcast float %unwrap2 to i32 1061 1062 ret i32 %valcast2 1063} 1064 1065define void @PR14059.1(ptr %d) { 1066; In PR14059 a peculiar construct was identified as something that is used 1067; pervasively in ARM's ABI-calling-convention lowering: the passing of a struct 1068; of doubles via an array of i32 in order to place the data into integer 1069; registers. This in turn was missed as an optimization by SROA due to the 1070; partial loads and stores of integers to the double alloca we were trying to 1071; form and promote. The solution is to widen the integer operations to be 1072; whole-alloca operations, and perform the appropriate bitcasting on the 1073; *values* rather than the pointers. When this works, partial reads and writes 1074; via integers can be promoted away. 1075; 1076; CHECK-LABEL: @PR14059.1( 1077; CHECK-NEXT: entry: 1078; CHECK-NEXT: [[TMP0:%.*]] = bitcast double undef to i64 1079; CHECK-NEXT: [[X_SROA_0_I_0_INSERT_MASK:%.*]] = and i64 [[TMP0]], -4294967296 1080; CHECK-NEXT: [[X_SROA_0_I_0_INSERT_INSERT:%.*]] = or i64 [[X_SROA_0_I_0_INSERT_MASK]], 0 1081; CHECK-NEXT: [[TMP1:%.*]] = bitcast i64 [[X_SROA_0_I_0_INSERT_INSERT]] to double 1082; CHECK-NEXT: [[TMP2:%.*]] = bitcast double [[TMP1]] to i64 1083; CHECK-NEXT: [[X_SROA_0_I_2_INSERT_MASK:%.*]] = and i64 [[TMP2]], -281474976645121 1084; CHECK-NEXT: [[X_SROA_0_I_2_INSERT_INSERT:%.*]] = or i64 [[X_SROA_0_I_2_INSERT_MASK]], 0 1085; CHECK-NEXT: [[TMP3:%.*]] = bitcast i64 [[X_SROA_0_I_2_INSERT_INSERT]] to double 1086; CHECK-NEXT: [[TMP4:%.*]] = bitcast double [[TMP3]] to i64 1087; CHECK-NEXT: [[X_SROA_0_I_4_COPYLOAD:%.*]] = load i32, ptr [[D:%.*]], align 1 1088; CHECK-NEXT: [[TMP5:%.*]] = bitcast double 0.000000e+00 to i64 1089; CHECK-NEXT: [[X_SROA_0_I_4_INSERT_EXT:%.*]] = zext i32 [[X_SROA_0_I_4_COPYLOAD]] to i64 1090; CHECK-NEXT: [[X_SROA_0_I_4_INSERT_SHIFT:%.*]] = shl i64 [[X_SROA_0_I_4_INSERT_EXT]], 32 1091; CHECK-NEXT: [[X_SROA_0_I_4_INSERT_MASK3:%.*]] = and i64 [[TMP5]], 4294967295 1092; CHECK-NEXT: [[X_SROA_0_I_4_INSERT_INSERT4:%.*]] = or i64 [[X_SROA_0_I_4_INSERT_MASK3]], [[X_SROA_0_I_4_INSERT_SHIFT]] 1093; CHECK-NEXT: [[TMP6:%.*]] = bitcast i64 [[X_SROA_0_I_4_INSERT_INSERT4]] to double 1094; CHECK-NEXT: [[TMP7:%.*]] = bitcast double [[TMP6]] to i64 1095; CHECK-NEXT: [[X_SROA_0_I_4_INSERT_MASK:%.*]] = and i64 [[TMP7]], 4294967295 1096; CHECK-NEXT: [[X_SROA_0_I_4_INSERT_INSERT:%.*]] = or i64 [[X_SROA_0_I_4_INSERT_MASK]], 4607182418800017408 1097; CHECK-NEXT: [[TMP8:%.*]] = bitcast i64 [[X_SROA_0_I_4_INSERT_INSERT]] to double 1098; CHECK-NEXT: [[ACCUM_REAL_I:%.*]] = load double, ptr [[D]], align 8 1099; CHECK-NEXT: [[ADD_R_I:%.*]] = fadd double [[ACCUM_REAL_I]], [[TMP8]] 1100; CHECK-NEXT: store double [[ADD_R_I]], ptr [[D]], align 8 1101; CHECK-NEXT: ret void 1102; 1103entry: 1104 %X.sroa.0.i = alloca double, align 8 1105 call void @llvm.lifetime.start.p0(i64 -1, ptr %X.sroa.0.i) 1106 1107 ; Store to the low 32-bits... 1108 store i32 0, ptr %X.sroa.0.i, align 8 1109 1110 ; Also use a memset to the middle 32-bits for fun. 1111 %X.sroa.0.2.raw_idx2.i = getelementptr inbounds i8, ptr %X.sroa.0.i, i32 2 1112 call void @llvm.memset.p0.i64(ptr %X.sroa.0.2.raw_idx2.i, i8 0, i64 4, i1 false) 1113 1114 ; Or a memset of the whole thing. 1115 call void @llvm.memset.p0.i64(ptr %X.sroa.0.i, i8 0, i64 8, i1 false) 1116 1117 ; Write to the high 32-bits with a memcpy. 1118 %X.sroa.0.4.raw_idx4.i = getelementptr inbounds i8, ptr %X.sroa.0.i, i32 4 1119 call void @llvm.memcpy.p0.p0.i32(ptr %X.sroa.0.4.raw_idx4.i, ptr %d, i32 4, i1 false) 1120 1121 ; Store to the high 32-bits... 1122 store i32 1072693248, ptr %X.sroa.0.4.raw_idx4.i, align 4 1123 1124 ; Do the actual math... 1125 %X.sroa.0.0.load1.i = load double, ptr %X.sroa.0.i, align 8 1126 %accum.real.i = load double, ptr %d, align 8 1127 %add.r.i = fadd double %accum.real.i, %X.sroa.0.0.load1.i 1128 store double %add.r.i, ptr %d, align 8 1129 call void @llvm.lifetime.end.p0(i64 -1, ptr %X.sroa.0.i) 1130 ret void 1131} 1132 1133define i64 @PR14059.2(ptr %phi) { 1134; Check that SROA can split up alloca-wide integer loads and stores where the 1135; underlying alloca has smaller components that are accessed independently. This 1136; shows up particularly with ABI lowering patterns coming out of Clang that rely 1137; on the particular register placement of a single large integer return value. 1138; 1139; CHECK-LABEL: @PR14059.2( 1140; CHECK-NEXT: entry: 1141; CHECK-NEXT: [[PHI_REALP:%.*]] = getelementptr inbounds { float, float }, ptr [[PHI:%.*]], i32 0, i32 0 1142; CHECK-NEXT: [[PHI_REAL:%.*]] = load float, ptr [[PHI_REALP]], align 4 1143; CHECK-NEXT: [[PHI_IMAGP:%.*]] = getelementptr inbounds { float, float }, ptr [[PHI]], i32 0, i32 1 1144; CHECK-NEXT: [[PHI_IMAG:%.*]] = load float, ptr [[PHI_IMAGP]], align 4 1145; CHECK-NEXT: [[TMP0:%.*]] = bitcast float [[PHI_REAL]] to i32 1146; CHECK-NEXT: [[TMP1:%.*]] = bitcast float [[PHI_IMAG]] to i32 1147; CHECK-NEXT: [[RETVAL_SROA_3_0_INSERT_EXT:%.*]] = zext i32 [[TMP1]] to i64 1148; CHECK-NEXT: [[RETVAL_SROA_3_0_INSERT_SHIFT:%.*]] = shl i64 [[RETVAL_SROA_3_0_INSERT_EXT]], 32 1149; CHECK-NEXT: [[RETVAL_SROA_3_0_INSERT_MASK:%.*]] = and i64 undef, 4294967295 1150; CHECK-NEXT: [[RETVAL_SROA_3_0_INSERT_INSERT:%.*]] = or i64 [[RETVAL_SROA_3_0_INSERT_MASK]], [[RETVAL_SROA_3_0_INSERT_SHIFT]] 1151; CHECK-NEXT: [[RETVAL_SROA_0_0_INSERT_EXT:%.*]] = zext i32 [[TMP0]] to i64 1152; CHECK-NEXT: [[RETVAL_SROA_0_0_INSERT_MASK:%.*]] = and i64 [[RETVAL_SROA_3_0_INSERT_INSERT]], -4294967296 1153; CHECK-NEXT: [[RETVAL_SROA_0_0_INSERT_INSERT:%.*]] = or i64 [[RETVAL_SROA_0_0_INSERT_MASK]], [[RETVAL_SROA_0_0_INSERT_EXT]] 1154; CHECK-NEXT: ret i64 [[RETVAL_SROA_0_0_INSERT_INSERT]] 1155; 1156entry: 1157 %retval = alloca { float, float }, align 4 1158 1159 store i64 0, ptr %retval 1160 1161 %phi.realp = getelementptr inbounds { float, float }, ptr %phi, i32 0, i32 0 1162 %phi.real = load float, ptr %phi.realp 1163 %phi.imagp = getelementptr inbounds { float, float }, ptr %phi, i32 0, i32 1 1164 %phi.imag = load float, ptr %phi.imagp 1165 1166 %real = getelementptr inbounds { float, float }, ptr %retval, i32 0, i32 0 1167 %imag = getelementptr inbounds { float, float }, ptr %retval, i32 0, i32 1 1168 store float %phi.real, ptr %real 1169 store float %phi.imag, ptr %imag 1170 1171 %0 = load i64, ptr %retval, align 1 1172 ret i64 %0 1173} 1174 1175define void @PR14105(ptr %ptr) { 1176; Ensure that when rewriting the GEP index '-1' for this alloca we preserve is 1177; sign as negative. We use a volatile memcpy to ensure promotion never actually 1178; occurs. 1179; 1180; CHECK-LABEL: @PR14105( 1181; CHECK-NEXT: entry: 1182; CHECK-NEXT: [[A_SROA_0:%.*]] = alloca [16 x i8], align 8 1183; CHECK-NEXT: [[GEP:%.*]] = getelementptr inbounds { [16 x i8] }, ptr [[PTR:%.*]], i64 -1 1184; CHECK-NEXT: call void @llvm.memcpy.p0.p0.i32(ptr align 8 [[GEP]], ptr align 8 [[A_SROA_0]], i32 16, i1 true) 1185; CHECK-NEXT: ret void 1186; 1187entry: 1188 %a = alloca { [16 x i8] }, align 8 1189 1190 %gep = getelementptr inbounds { [16 x i8] }, ptr %ptr, i64 -1 1191 1192 call void @llvm.memcpy.p0.p0.i32(ptr align 8 %gep, ptr align 8 %a, i32 16, i1 true) 1193 ret void 1194} 1195 1196define void @PR14105_as1(ptr addrspace(1) %ptr) { 1197; Make sure this the right address space pointer is used for type check. 1198; 1199; CHECK-LABEL: @PR14105_as1( 1200; CHECK-NEXT: entry: 1201; CHECK-NEXT: [[A_SROA_0:%.*]] = alloca [16 x i8], align 8 1202; CHECK-NEXT: [[GEP:%.*]] = getelementptr inbounds { [16 x i8] }, ptr addrspace(1) [[PTR:%.*]], i64 -1 1203; CHECK-NEXT: call void @llvm.memcpy.p1.p0.i32(ptr addrspace(1) align 8 [[GEP]], ptr align 8 [[A_SROA_0]], i32 16, i1 true) 1204; CHECK-NEXT: ret void 1205; 1206entry: 1207 %a = alloca { [16 x i8] }, align 8 1208 %gep = getelementptr inbounds { [16 x i8] }, ptr addrspace(1) %ptr, i64 -1 1209 call void @llvm.memcpy.p1.p0.i32(ptr addrspace(1) align 8 %gep, ptr align 8 %a, i32 16, i1 true) 1210 ret void 1211} 1212 1213define void @PR14465() { 1214; Ensure that we don't crash when analyzing a alloca larger than the maximum 1215; integer type width (MAX_INT_BITS) supported by llvm (1048576*32 > (1<<23)-1). 1216; 1217; CHECK-LABEL: @PR14465( 1218; CHECK-NEXT: [[STACK:%.*]] = alloca [1048576 x i32], align 16 1219; CHECK-NEXT: call void @llvm.memset.p0.i64(ptr align 16 [[STACK]], i8 -2, i64 4194304, i1 false) 1220; CHECK-NEXT: ret void 1221; 1222 %stack = alloca [1048576 x i32], align 16 1223 call void @llvm.memset.p0.i64(ptr align 16 %stack, i8 -2, i64 4194304, i1 false) 1224 ret void 1225} 1226 1227define void @PR14548(i1 %x) { 1228; Handle a mixture of i1 and i8 loads and stores to allocas. This particular 1229; pattern caused crashes and invalid output in the PR, and its nature will 1230; trigger a mixture in several permutations as we resolve each alloca 1231; iteratively. 1232; Note that we don't do a particularly good *job* of handling these mixtures, 1233; but the hope is that this is very rare. 1234; 1235; CHECK-LABEL: @PR14548( 1236; CHECK-NEXT: entry: 1237; CHECK-NEXT: [[A_SROA_0:%.*]] = alloca i8, align 8 1238; CHECK-NEXT: [[B_SROA_0:%.*]] = alloca i8, align 8 1239; CHECK-NEXT: store i1 [[X:%.*]], ptr [[B_SROA_0]], align 8 1240; CHECK-NEXT: [[B_SROA_0_0_B_SROA_0_0_FOO:%.*]] = load i8, ptr [[B_SROA_0]], align 8 1241; CHECK-NEXT: [[B_SROA_0_0_B_SROA_0_0_COPYLOAD:%.*]] = load i8, ptr [[B_SROA_0]], align 8 1242; CHECK-NEXT: store i8 [[B_SROA_0_0_B_SROA_0_0_COPYLOAD]], ptr [[A_SROA_0]], align 8 1243; CHECK-NEXT: [[A_SROA_0_0_A_SROA_0_0_BAR:%.*]] = load i8, ptr [[A_SROA_0]], align 8 1244; CHECK-NEXT: [[A_SROA_0_0_A_SROA_0_0_BAZ:%.*]] = load i1, ptr [[A_SROA_0]], align 8 1245; CHECK-NEXT: ret void 1246; 1247entry: 1248 %a = alloca <{ i1 }>, align 8 1249 %b = alloca <{ i1 }>, align 8 1250 1251 store i1 %x, ptr %b, align 8 1252 %foo = load i8, ptr %b, align 1 1253 1254 call void @llvm.memcpy.p0.p0.i32(ptr %a, ptr %b, i32 1, i1 false) nounwind 1255 %bar = load i8, ptr %a, align 1 1256 %baz = load i1, ptr %a, align 1 1257 1258 ret void 1259} 1260 1261define <3 x i8> @PR14572.1(i32 %x) { 1262; Ensure that a split integer store which is wider than the type size of the 1263; alloca (relying on the alloc size padding) doesn't trigger an assert. 1264; 1265; CHECK-LABEL: @PR14572.1( 1266; CHECK-NEXT: entry: 1267; CHECK-NEXT: [[A_0_EXTRACT_TRUNC:%.*]] = trunc i32 [[X:%.*]] to i24 1268; CHECK-NEXT: [[TMP0:%.*]] = bitcast i24 [[A_0_EXTRACT_TRUNC]] to <3 x i8> 1269; CHECK-NEXT: [[A_SROA_2_0_EXTRACT_SHIFT:%.*]] = lshr i32 [[X]], 24 1270; CHECK-NEXT: [[A_SROA_2_0_EXTRACT_TRUNC:%.*]] = trunc i32 [[A_SROA_2_0_EXTRACT_SHIFT]] to i8 1271; CHECK-NEXT: ret <3 x i8> [[TMP0]] 1272; 1273entry: 1274 %a = alloca <3 x i8>, align 4 1275 1276 store i32 %x, ptr %a, align 1 1277 %y = load <3 x i8>, ptr %a, align 4 1278 ret <3 x i8> %y 1279} 1280 1281define i32 @PR14572.2(<3 x i8> %x) { 1282; Ensure that a split integer load which is wider than the type size of the 1283; alloca (relying on the alloc size padding) doesn't trigger an assert. 1284; 1285; CHECK-LABEL: @PR14572.2( 1286; CHECK-NEXT: entry: 1287; CHECK-NEXT: [[TMP0:%.*]] = bitcast <3 x i8> [[X:%.*]] to i24 1288; CHECK-NEXT: [[A_SROA_2_0_INSERT_EXT:%.*]] = zext i8 undef to i32 1289; CHECK-NEXT: [[A_SROA_2_0_INSERT_SHIFT:%.*]] = shl i32 [[A_SROA_2_0_INSERT_EXT]], 24 1290; CHECK-NEXT: [[A_SROA_2_0_INSERT_MASK:%.*]] = and i32 undef, 16777215 1291; CHECK-NEXT: [[A_SROA_2_0_INSERT_INSERT:%.*]] = or i32 [[A_SROA_2_0_INSERT_MASK]], [[A_SROA_2_0_INSERT_SHIFT]] 1292; CHECK-NEXT: [[A_0_INSERT_EXT:%.*]] = zext i24 [[TMP0]] to i32 1293; CHECK-NEXT: [[A_0_INSERT_MASK:%.*]] = and i32 [[A_SROA_2_0_INSERT_INSERT]], -16777216 1294; CHECK-NEXT: [[A_0_INSERT_INSERT:%.*]] = or i32 [[A_0_INSERT_MASK]], [[A_0_INSERT_EXT]] 1295; CHECK-NEXT: ret i32 [[A_0_INSERT_INSERT]] 1296; 1297entry: 1298 %a = alloca <3 x i8>, align 4 1299 1300 store <3 x i8> %x, ptr %a, align 1 1301 %y = load i32, ptr %a, align 4 1302 ret i32 %y 1303} 1304 1305define i32 @PR14601(i32 %x) { 1306; Don't try to form a promotable integer alloca when there is a variable length 1307; memory intrinsic. 1308; 1309; CHECK-LABEL: @PR14601( 1310; CHECK-NEXT: entry: 1311; CHECK-NEXT: [[A:%.*]] = alloca i32, align 4 1312; CHECK-NEXT: call void @llvm.memset.p0.i32(ptr align 4 [[A]], i8 0, i32 [[X:%.*]], i1 false) 1313; CHECK-NEXT: [[A_0_V:%.*]] = load i32, ptr [[A]], align 4 1314; CHECK-NEXT: ret i32 [[A_0_V]] 1315; 1316entry: 1317 %a = alloca i32 1318 1319 call void @llvm.memset.p0.i32(ptr %a, i8 0, i32 %x, i1 false) 1320 %v = load i32, ptr %a 1321 ret i32 %v 1322} 1323 1324define void @PR15674(ptr %data, ptr %src, i32 %size) { 1325; Arrange (via control flow) to have unmerged stores of a particular width to 1326; an alloca where we incrementally store from the end of the array toward the 1327; beginning of the array. Ensure that the final integer store, despite being 1328; convertable to the integer type that we end up promoting this alloca toward, 1329; doesn't get widened to a full alloca store. 1330; 1331; CHECK-LABEL: @PR15674( 1332; CHECK-NEXT: entry: 1333; CHECK-NEXT: [[TMP_SROA_0:%.*]] = alloca i32, align 4 1334; CHECK-NEXT: switch i32 [[SIZE:%.*]], label [[END:%.*]] [ 1335; CHECK-NEXT: i32 4, label [[BB4:%.*]] 1336; CHECK-NEXT: i32 3, label [[BB3:%.*]] 1337; CHECK-NEXT: i32 2, label [[BB2:%.*]] 1338; CHECK-NEXT: i32 1, label [[BB1:%.*]] 1339; CHECK-NEXT: ] 1340; CHECK: bb4: 1341; CHECK-NEXT: [[SRC_GEP3:%.*]] = getelementptr inbounds i8, ptr [[SRC:%.*]], i32 3 1342; CHECK-NEXT: [[SRC_3:%.*]] = load i8, ptr [[SRC_GEP3]], align 1 1343; CHECK-NEXT: [[TMP_SROA_0_3_TMP_GEP3_SROA_IDX3:%.*]] = getelementptr inbounds i8, ptr [[TMP_SROA_0]], i64 3 1344; CHECK-NEXT: store i8 [[SRC_3]], ptr [[TMP_SROA_0_3_TMP_GEP3_SROA_IDX3]], align 1 1345; CHECK-NEXT: br label [[BB3]] 1346; CHECK: bb3: 1347; CHECK-NEXT: [[SRC_GEP2:%.*]] = getelementptr inbounds i8, ptr [[SRC]], i32 2 1348; CHECK-NEXT: [[SRC_2:%.*]] = load i8, ptr [[SRC_GEP2]], align 1 1349; CHECK-NEXT: [[TMP_SROA_0_2_TMP_GEP2_SROA_IDX2:%.*]] = getelementptr inbounds i8, ptr [[TMP_SROA_0]], i64 2 1350; CHECK-NEXT: store i8 [[SRC_2]], ptr [[TMP_SROA_0_2_TMP_GEP2_SROA_IDX2]], align 2 1351; CHECK-NEXT: br label [[BB2]] 1352; CHECK: bb2: 1353; CHECK-NEXT: [[SRC_GEP1:%.*]] = getelementptr inbounds i8, ptr [[SRC]], i32 1 1354; CHECK-NEXT: [[SRC_1:%.*]] = load i8, ptr [[SRC_GEP1]], align 1 1355; CHECK-NEXT: [[TMP_SROA_0_1_TMP_GEP1_SROA_IDX1:%.*]] = getelementptr inbounds i8, ptr [[TMP_SROA_0]], i64 1 1356; CHECK-NEXT: store i8 [[SRC_1]], ptr [[TMP_SROA_0_1_TMP_GEP1_SROA_IDX1]], align 1 1357; CHECK-NEXT: br label [[BB1]] 1358; CHECK: bb1: 1359; CHECK-NEXT: [[SRC_0:%.*]] = load i8, ptr [[SRC]], align 1 1360; CHECK-NEXT: store i8 [[SRC_0]], ptr [[TMP_SROA_0]], align 4 1361; CHECK-NEXT: br label [[END]] 1362; CHECK: end: 1363; CHECK-NEXT: call void @llvm.memcpy.p0.p0.i32(ptr [[DATA:%.*]], ptr align 4 [[TMP_SROA_0]], i32 [[SIZE]], i1 false) 1364; CHECK-NEXT: ret void 1365; 1366entry: 1367 %tmp = alloca [4 x i8], align 1 1368 1369 switch i32 %size, label %end [ 1370 i32 4, label %bb4 1371 i32 3, label %bb3 1372 i32 2, label %bb2 1373 i32 1, label %bb1 1374 ] 1375 1376bb4: 1377 %src.gep3 = getelementptr inbounds i8, ptr %src, i32 3 1378 %src.3 = load i8, ptr %src.gep3 1379 %tmp.gep3 = getelementptr inbounds [4 x i8], ptr %tmp, i32 0, i32 3 1380 store i8 %src.3, ptr %tmp.gep3 1381 1382 br label %bb3 1383 1384bb3: 1385 %src.gep2 = getelementptr inbounds i8, ptr %src, i32 2 1386 %src.2 = load i8, ptr %src.gep2 1387 %tmp.gep2 = getelementptr inbounds [4 x i8], ptr %tmp, i32 0, i32 2 1388 store i8 %src.2, ptr %tmp.gep2 1389 1390 br label %bb2 1391 1392bb2: 1393 %src.gep1 = getelementptr inbounds i8, ptr %src, i32 1 1394 %src.1 = load i8, ptr %src.gep1 1395 %tmp.gep1 = getelementptr inbounds [4 x i8], ptr %tmp, i32 0, i32 1 1396 store i8 %src.1, ptr %tmp.gep1 1397 1398 br label %bb1 1399 1400bb1: 1401 %src.0 = load i8, ptr %src 1402 store i8 %src.0, ptr %tmp 1403 1404 br label %end 1405 1406end: 1407 call void @llvm.memcpy.p0.p0.i32(ptr %data, ptr %tmp, i32 %size, i1 false) 1408 ret void 1409} 1410 1411define void @PR15805(i1 %a, i1 %b) { 1412; CHECK-PRESERVE-CFG-LABEL: @PR15805( 1413; CHECK-PRESERVE-CFG-NEXT: [[C:%.*]] = alloca i64, align 8 1414; CHECK-PRESERVE-CFG-NEXT: [[COND_IN:%.*]] = select i1 [[B:%.*]], ptr [[C]], ptr [[C]] 1415; CHECK-PRESERVE-CFG-NEXT: [[COND:%.*]] = load i64, ptr [[COND_IN]], align 8 1416; CHECK-PRESERVE-CFG-NEXT: ret void 1417; 1418; CHECK-MODIFY-CFG-LABEL: @PR15805( 1419; CHECK-MODIFY-CFG-NEXT: br i1 [[B:%.*]], label [[DOTCONT:%.*]], label [[DOTELSE:%.*]] 1420; CHECK-MODIFY-CFG: .else: 1421; CHECK-MODIFY-CFG-NEXT: br label [[DOTCONT]] 1422; CHECK-MODIFY-CFG: .cont: 1423; CHECK-MODIFY-CFG-NEXT: [[COND:%.*]] = phi i64 [ undef, [[TMP0:%.*]] ], [ undef, [[DOTELSE]] ] 1424; CHECK-MODIFY-CFG-NEXT: ret void 1425; 1426 %c = alloca i64, align 8 1427 %p.0.c = select i1 %a, ptr %c, ptr %c 1428 %cond.in = select i1 %b, ptr %p.0.c, ptr %c 1429 %cond = load i64, ptr %cond.in, align 8 1430 ret void 1431} 1432 1433define void @PR15805.1(i1 %a, i1 %b, i1 %c2) { 1434; Same as the normal PR15805, but rigged to place the use before the def inside 1435; of looping unreachable code. This helps ensure that we aren't sensitive to the 1436; order in which the uses of the alloca are visited. 1437; 1438; 1439; CHECK-PRESERVE-CFG-LABEL: @PR15805.1( 1440; CHECK-PRESERVE-CFG-NEXT: [[C:%.*]] = alloca i64, align 8 1441; CHECK-PRESERVE-CFG-NEXT: br label [[EXIT:%.*]] 1442; CHECK-PRESERVE-CFG: loop: 1443; CHECK-PRESERVE-CFG-NEXT: [[COND_IN:%.*]] = select i1 [[A:%.*]], ptr [[C]], ptr [[C]] 1444; CHECK-PRESERVE-CFG-NEXT: [[COND:%.*]] = load i64, ptr [[COND_IN]], align 8 1445; CHECK-PRESERVE-CFG-NEXT: br i1 [[C2:%.*]], label [[LOOP:%.*]], label [[EXIT]] 1446; CHECK-PRESERVE-CFG: exit: 1447; CHECK-PRESERVE-CFG-NEXT: ret void 1448; 1449; CHECK-MODIFY-CFG-LABEL: @PR15805.1( 1450; CHECK-MODIFY-CFG-NEXT: br label [[EXIT:%.*]] 1451; CHECK-MODIFY-CFG: loop: 1452; CHECK-MODIFY-CFG-NEXT: [[C_0_LOAD:%.*]] = load i64, ptr poison, align 8 1453; CHECK-MODIFY-CFG-NEXT: br i1 [[A:%.*]], label [[LOOP_CONT:%.*]], label [[LOOP_ELSE:%.*]] 1454; CHECK-MODIFY-CFG: loop.else: 1455; CHECK-MODIFY-CFG-NEXT: [[C_0_LOAD1:%.*]] = load i64, ptr poison, align 8 1456; CHECK-MODIFY-CFG-NEXT: br label [[LOOP_CONT]] 1457; CHECK-MODIFY-CFG: loop.cont: 1458; CHECK-MODIFY-CFG-NEXT: [[COND:%.*]] = phi i64 [ [[C_0_LOAD]], [[LOOP:%.*]] ], [ [[C_0_LOAD1]], [[LOOP_ELSE]] ] 1459; CHECK-MODIFY-CFG-NEXT: br i1 [[C2:%.*]], label [[LOOP]], label [[EXIT]] 1460; CHECK-MODIFY-CFG: exit: 1461; CHECK-MODIFY-CFG-NEXT: ret void 1462; 1463 %c = alloca i64, align 8 1464 br label %exit 1465 1466loop: 1467 %cond.in = select i1 %a, ptr %c, ptr %p.0.c 1468 %p.0.c = select i1 %b, ptr %c, ptr %c 1469 %cond = load i64, ptr %cond.in, align 8 1470 br i1 %c2, label %loop, label %exit 1471 1472exit: 1473 ret void 1474} 1475 1476define void @PR16651.1(ptr %a) { 1477; This test case caused a crash due to the volatile memcpy in combination with 1478; lowering to integer loads and stores of a width other than that of the original 1479; memcpy. 1480; 1481; 1482; CHECK-LABEL: @PR16651.1( 1483; CHECK-NEXT: entry: 1484; CHECK-NEXT: [[B_SROA_0:%.*]] = alloca i16, align 4 1485; CHECK-NEXT: [[B_SROA_1:%.*]] = alloca i8, align 2 1486; CHECK-NEXT: [[B_SROA_2:%.*]] = alloca i8, align 1 1487; CHECK-NEXT: [[B_SROA_0_0_COPYLOAD:%.*]] = load volatile i16, ptr [[A:%.*]], align 4 1488; CHECK-NEXT: store volatile i16 [[B_SROA_0_0_COPYLOAD]], ptr [[B_SROA_0]], align 4 1489; CHECK-NEXT: [[B_SROA_1_0_A_SROA_IDX:%.*]] = getelementptr inbounds i8, ptr [[A]], i64 2 1490; CHECK-NEXT: [[B_SROA_1_0_COPYLOAD:%.*]] = load volatile i8, ptr [[B_SROA_1_0_A_SROA_IDX]], align 2 1491; CHECK-NEXT: store volatile i8 [[B_SROA_1_0_COPYLOAD]], ptr [[B_SROA_1]], align 2 1492; CHECK-NEXT: [[B_SROA_2_0_A_SROA_IDX:%.*]] = getelementptr inbounds i8, ptr [[A]], i64 3 1493; CHECK-NEXT: [[B_SROA_2_0_COPYLOAD:%.*]] = load volatile i8, ptr [[B_SROA_2_0_A_SROA_IDX]], align 1 1494; CHECK-NEXT: store volatile i8 [[B_SROA_2_0_COPYLOAD]], ptr [[B_SROA_2]], align 1 1495; CHECK-NEXT: [[B_SROA_1_0_B_SROA_1_2_:%.*]] = load i8, ptr [[B_SROA_1]], align 2 1496; CHECK-NEXT: unreachable 1497; 1498entry: 1499 %b = alloca i32, align 4 1500 call void @llvm.memcpy.p0.p0.i32(ptr align 4 %b, ptr align 4 %a, i32 4, i1 true) 1501 %b.gep = getelementptr inbounds i8, ptr %b, i32 2 1502 load i8, ptr %b.gep, align 2 1503 unreachable 1504} 1505 1506define void @PR16651.2(<2 x float> %val, i1 %c1) { 1507; This test case caused a crash due to failing to promote given a select that 1508; can't be speculated. It shouldn't be promoted, but we missed that fact when 1509; analyzing whether we could form a vector promotion because that code didn't 1510; bail on select instructions. 1511; 1512; 1513; CHECK-PRESERVE-CFG-LABEL: @PR16651.2( 1514; CHECK-PRESERVE-CFG-NEXT: entry: 1515; CHECK-PRESERVE-CFG-NEXT: [[TV1_SROA_0:%.*]] = alloca <2 x float>, align 8 1516; CHECK-PRESERVE-CFG-NEXT: store <2 x float> [[VAL:%.*]], ptr [[TV1_SROA_0]], align 8 1517; CHECK-PRESERVE-CFG-NEXT: [[COND105_IN_I_I:%.*]] = select i1 [[C1:%.*]], ptr null, ptr [[TV1_SROA_0]] 1518; CHECK-PRESERVE-CFG-NEXT: [[COND105_I_I:%.*]] = load float, ptr [[COND105_IN_I_I]], align 8 1519; CHECK-PRESERVE-CFG-NEXT: ret void 1520; 1521; CHECK-MODIFY-CFG-LABEL: @PR16651.2( 1522; CHECK-MODIFY-CFG-NEXT: entry: 1523; CHECK-MODIFY-CFG-NEXT: [[TV1_SROA_0_0_VEC_EXTRACT:%.*]] = extractelement <2 x float> [[VAL:%.*]], i32 0 1524; CHECK-MODIFY-CFG-NEXT: br i1 [[C1:%.*]], label [[ENTRY_THEN:%.*]], label [[ENTRY_CONT:%.*]] 1525; CHECK-MODIFY-CFG: entry.then: 1526; CHECK-MODIFY-CFG-NEXT: [[COND105_I_I_THEN_VAL:%.*]] = load float, ptr null, align 8 1527; CHECK-MODIFY-CFG-NEXT: br label [[ENTRY_CONT]] 1528; CHECK-MODIFY-CFG: entry.cont: 1529; CHECK-MODIFY-CFG-NEXT: [[COND105_I_I:%.*]] = phi float [ [[COND105_I_I_THEN_VAL]], [[ENTRY_THEN]] ], [ [[TV1_SROA_0_0_VEC_EXTRACT]], [[ENTRY:%.*]] ] 1530; CHECK-MODIFY-CFG-NEXT: ret void 1531; 1532entry: 1533 %tv1 = alloca { <2 x float>, <2 x float> }, align 8 1534 %0 = getelementptr { <2 x float>, <2 x float> }, ptr %tv1, i64 0, i32 1 1535 store <2 x float> %val, ptr %0, align 8 1536 %1 = getelementptr inbounds { <2 x float>, <2 x float> }, ptr %tv1, i64 0, i32 1, i64 0 1537 %cond105.in.i.i = select i1 %c1, ptr null, ptr %1 1538 %cond105.i.i = load float, ptr %cond105.in.i.i, align 8 1539 ret void 1540} 1541 1542define void @test23(i32 %x) { 1543; CHECK-LABEL: @test23( 1544; CHECK-NEXT: entry: 1545; CHECK-NEXT: ret void 1546; 1547entry: 1548 %a = alloca i32, align 4 1549 store i32 %x, ptr %a, align 4 1550 %gep1 = getelementptr inbounds i32, ptr %a, i32 1 1551 call void @llvm.memcpy.p0.p0.i32(ptr %gep1, ptr %a, i32 4, i1 false) 1552 ret void 1553} 1554 1555define void @PR18615(ptr %ptr) { 1556; CHECK-LABEL: @PR18615( 1557; CHECK-NEXT: entry: 1558; CHECK-NEXT: ret void 1559; 1560entry: 1561 %f = alloca i8 1562 %gep = getelementptr i8, ptr %f, i64 -1 1563 call void @llvm.memcpy.p0.p0.i32(ptr %ptr, ptr %gep, i32 1, i1 false) 1564 ret void 1565} 1566 1567define void @test24(ptr %src, ptr %dst) { 1568; CHECK-LABEL: @test24( 1569; CHECK-NEXT: entry: 1570; CHECK-NEXT: [[A:%.*]] = alloca i64, align 16 1571; CHECK-NEXT: [[A_0_COPYLOAD:%.*]] = load volatile i64, ptr [[SRC:%.*]], align 1, !tbaa [[TBAA0]] 1572; CHECK-NEXT: store volatile i64 [[A_0_COPYLOAD]], ptr [[A]], align 16, !tbaa [[TBAA0]] 1573; CHECK-NEXT: [[A_0_COPYLOAD1:%.*]] = load volatile i64, ptr [[A]], align 16, !tbaa [[TBAA3]] 1574; CHECK-NEXT: store volatile i64 [[A_0_COPYLOAD1]], ptr [[DST:%.*]], align 1, !tbaa [[TBAA3]] 1575; CHECK-NEXT: ret void 1576; 1577entry: 1578 %a = alloca i64, align 16 1579 call void @llvm.memcpy.p0.p0.i32(ptr %a, ptr %src, i32 8, i1 true), !tbaa !0 1580 call void @llvm.memcpy.p0.p0.i32(ptr %dst, ptr %a, i32 8, i1 true), !tbaa !3 1581 ret void 1582} 1583 1584define float @test25() { 1585; Check that we split up stores in order to promote the smaller SSA values.. These types 1586; of patterns can arise because LLVM maps small memcpy's to integer load and 1587; stores. If we get a memcpy of an aggregate (such as C and C++ frontends would 1588; produce, but so might any language frontend), this will in many cases turn into 1589; an integer load and store. SROA needs to be extremely powerful to correctly 1590; handle these cases and form splitable and promotable SSA values. 1591; 1592; 1593; CHECK-LABEL: @test25( 1594; CHECK-NEXT: entry: 1595; CHECK-NEXT: [[TMP0:%.*]] = bitcast i32 0 to float 1596; CHECK-NEXT: [[TMP1:%.*]] = bitcast i32 1065353216 to float 1597; CHECK-NEXT: [[RET:%.*]] = fadd float [[TMP0]], [[TMP1]] 1598; CHECK-NEXT: ret float [[RET]] 1599; 1600entry: 1601 %a = alloca i64 1602 %b = alloca i64 1603 %a.gep2 = getelementptr [2 x float], ptr %a, i32 0, i32 1 1604 %b.gep2 = getelementptr [2 x float], ptr %b, i32 0, i32 1 1605 store float 0.0, ptr %a 1606 store float 1.0, ptr %a.gep2 1607 %v = load i64, ptr %a 1608 store i64 %v, ptr %b 1609 %f1 = load float, ptr %b 1610 %f2 = load float, ptr %b.gep2 1611 %ret = fadd float %f1, %f2 1612 ret float %ret 1613} 1614 1615@complex1 = external global [2 x float] 1616@complex2 = external global [2 x float] 1617 1618define void @test26() { 1619; Test a case of splitting up loads and stores against a globals. 1620; 1621; 1622; CHECK-LABEL: @test26( 1623; CHECK-NEXT: entry: 1624; CHECK-NEXT: [[V13:%.*]] = load i32, ptr @complex1, align 4 1625; CHECK-NEXT: [[V14:%.*]] = load i32, ptr getelementptr inbounds (i8, ptr @complex1, i64 4), align 4 1626; CHECK-NEXT: [[TMP0:%.*]] = bitcast i32 [[V13]] to float 1627; CHECK-NEXT: [[TMP1:%.*]] = bitcast i32 [[V14]] to float 1628; CHECK-NEXT: [[SUM:%.*]] = fadd float [[TMP0]], [[TMP1]] 1629; CHECK-NEXT: [[TMP2:%.*]] = bitcast float [[SUM]] to i32 1630; CHECK-NEXT: [[TMP3:%.*]] = bitcast float [[SUM]] to i32 1631; CHECK-NEXT: store i32 [[TMP2]], ptr @complex2, align 4 1632; CHECK-NEXT: store i32 [[TMP3]], ptr getelementptr inbounds (i8, ptr @complex2, i64 4), align 4 1633; CHECK-NEXT: ret void 1634; 1635entry: 1636 %a = alloca i64 1637 %a.gep2 = getelementptr [2 x float], ptr %a, i32 0, i32 1 1638 %v1 = load i64, ptr @complex1 1639 store i64 %v1, ptr %a 1640 %f1 = load float, ptr %a 1641 %f2 = load float, ptr %a.gep2 1642 %sum = fadd float %f1, %f2 1643 store float %sum, ptr %a 1644 store float %sum, ptr %a.gep2 1645 %v2 = load i64, ptr %a 1646 store i64 %v2, ptr @complex2 1647 ret void 1648} 1649 1650define float @test27() { 1651; Another, more complex case of splittable i64 loads and stores. This example 1652; is a particularly challenging one because the load and store both point into 1653; the alloca SROA is processing, and they overlap but at an offset. 1654; 1655; 1656; CHECK-LABEL: @test27( 1657; CHECK-NEXT: entry: 1658; CHECK-NEXT: [[TMP0:%.*]] = bitcast i32 0 to float 1659; CHECK-NEXT: [[TMP1:%.*]] = bitcast i32 1065353216 to float 1660; CHECK-NEXT: [[RET:%.*]] = fadd float [[TMP0]], [[TMP1]] 1661; CHECK-NEXT: ret float [[RET]] 1662; 1663entry: 1664 %a = alloca [12 x i8] 1665 %gep2 = getelementptr [12 x i8], ptr %a, i32 0, i32 4 1666 %gep3 = getelementptr [12 x i8], ptr %a, i32 0, i32 8 1667 store float 0.0, ptr %a 1668 store float 1.0, ptr %gep2 1669 %v = load i64, ptr %a 1670 store i64 %v, ptr %gep2 1671 %f1 = load float, ptr %gep2 1672 %f2 = load float, ptr %gep3 1673 %ret = fadd float %f1, %f2 1674 ret float %ret 1675} 1676 1677define i32 @PR22093() { 1678; Test that we don't try to pre-split a splittable store of a splittable but 1679; not pre-splittable load over the same alloca. We "handle" this case when the 1680; load is unsplittable but unrelated to this alloca by just generating extra 1681; loads without touching the original, but when the original load was out of 1682; this alloca we need to handle it specially to ensure the splits line up 1683; properly for rewriting. 1684; 1685; 1686; CHECK-LABEL: @PR22093( 1687; CHECK-NEXT: entry: 1688; CHECK-NEXT: [[A_SROA_0:%.*]] = alloca i16, align 4 1689; CHECK-NEXT: store volatile i16 42, ptr [[A_SROA_0]], align 4 1690; CHECK-NEXT: [[A_SROA_0_0_A_SROA_0_0_LOAD:%.*]] = load i16, ptr [[A_SROA_0]], align 4 1691; CHECK-NEXT: [[A_SROA_3_0_INSERT_EXT:%.*]] = zext i16 undef to i32 1692; CHECK-NEXT: [[A_SROA_3_0_INSERT_SHIFT:%.*]] = shl i32 [[A_SROA_3_0_INSERT_EXT]], 16 1693; CHECK-NEXT: [[A_SROA_3_0_INSERT_MASK:%.*]] = and i32 undef, 65535 1694; CHECK-NEXT: [[A_SROA_3_0_INSERT_INSERT:%.*]] = or i32 [[A_SROA_3_0_INSERT_MASK]], [[A_SROA_3_0_INSERT_SHIFT]] 1695; CHECK-NEXT: [[A_SROA_0_0_INSERT_EXT:%.*]] = zext i16 [[A_SROA_0_0_A_SROA_0_0_LOAD]] to i32 1696; CHECK-NEXT: [[A_SROA_0_0_INSERT_MASK:%.*]] = and i32 [[A_SROA_3_0_INSERT_INSERT]], -65536 1697; CHECK-NEXT: [[A_SROA_0_0_INSERT_INSERT:%.*]] = or i32 [[A_SROA_0_0_INSERT_MASK]], [[A_SROA_0_0_INSERT_EXT]] 1698; CHECK-NEXT: [[A_SROA_0_0_EXTRACT_TRUNC:%.*]] = trunc i32 [[A_SROA_0_0_INSERT_INSERT]] to i16 1699; CHECK-NEXT: store i16 [[A_SROA_0_0_EXTRACT_TRUNC]], ptr [[A_SROA_0]], align 4 1700; CHECK-NEXT: [[A_SROA_3_0_EXTRACT_SHIFT:%.*]] = lshr i32 [[A_SROA_0_0_INSERT_INSERT]], 16 1701; CHECK-NEXT: [[A_SROA_3_0_EXTRACT_TRUNC:%.*]] = trunc i32 [[A_SROA_3_0_EXTRACT_SHIFT]] to i16 1702; CHECK-NEXT: ret i32 [[A_SROA_0_0_INSERT_INSERT]] 1703; 1704entry: 1705 %a = alloca i32 1706 store volatile i16 42, ptr %a 1707 %load = load i32, ptr %a 1708 store i32 %load, ptr %a 1709 ret i32 %load 1710} 1711 1712define void @PR22093.2() { 1713; Another way that we end up being unable to split a particular set of loads 1714; and stores can even have ordering importance. Here we have a load which is 1715; pre-splittable by itself, and the first store is also compatible. But the 1716; second store of the load makes the load unsplittable because of a mismatch of 1717; splits. Because this makes the load unsplittable, we also have to go back and 1718; remove the first store from the presplit candidates as its load won't be 1719; presplit. 1720; 1721; 1722; CHECK-LABEL: @PR22093.2( 1723; CHECK-NEXT: entry: 1724; CHECK-NEXT: [[A_SROA_0:%.*]] = alloca i16, align 8 1725; CHECK-NEXT: [[A_SROA_31:%.*]] = alloca i8, align 4 1726; CHECK-NEXT: store volatile i16 42, ptr [[A_SROA_0]], align 8 1727; CHECK-NEXT: [[A_SROA_0_0_A_SROA_0_0_LOAD:%.*]] = load i16, ptr [[A_SROA_0]], align 8 1728; CHECK-NEXT: [[A_SROA_3_0_INSERT_EXT:%.*]] = zext i16 undef to i32 1729; CHECK-NEXT: [[A_SROA_3_0_INSERT_SHIFT:%.*]] = shl i32 [[A_SROA_3_0_INSERT_EXT]], 16 1730; CHECK-NEXT: [[A_SROA_3_0_INSERT_MASK:%.*]] = and i32 undef, 65535 1731; CHECK-NEXT: [[A_SROA_3_0_INSERT_INSERT:%.*]] = or i32 [[A_SROA_3_0_INSERT_MASK]], [[A_SROA_3_0_INSERT_SHIFT]] 1732; CHECK-NEXT: [[A_SROA_0_0_INSERT_EXT:%.*]] = zext i16 [[A_SROA_0_0_A_SROA_0_0_LOAD]] to i32 1733; CHECK-NEXT: [[A_SROA_0_0_INSERT_MASK:%.*]] = and i32 [[A_SROA_3_0_INSERT_INSERT]], -65536 1734; CHECK-NEXT: [[A_SROA_0_0_INSERT_INSERT:%.*]] = or i32 [[A_SROA_0_0_INSERT_MASK]], [[A_SROA_0_0_INSERT_EXT]] 1735; CHECK-NEXT: [[A_SROA_0_0_EXTRACT_TRUNC:%.*]] = trunc i32 [[A_SROA_0_0_INSERT_INSERT]] to i16 1736; CHECK-NEXT: store i16 [[A_SROA_0_0_EXTRACT_TRUNC]], ptr [[A_SROA_0]], align 8 1737; CHECK-NEXT: [[A_SROA_3_0_EXTRACT_SHIFT:%.*]] = lshr i32 [[A_SROA_0_0_INSERT_INSERT]], 16 1738; CHECK-NEXT: [[A_SROA_3_0_EXTRACT_TRUNC:%.*]] = trunc i32 [[A_SROA_3_0_EXTRACT_SHIFT]] to i16 1739; CHECK-NEXT: store volatile i8 13, ptr [[A_SROA_31]], align 4 1740; CHECK-NEXT: [[A_SROA_31_4_EXTRACT_TRUNC:%.*]] = trunc i32 [[A_SROA_0_0_INSERT_INSERT]] to i8 1741; CHECK-NEXT: store i8 [[A_SROA_31_4_EXTRACT_TRUNC]], ptr [[A_SROA_31]], align 4 1742; CHECK-NEXT: [[A_SROA_5_4_EXTRACT_SHIFT:%.*]] = lshr i32 [[A_SROA_0_0_INSERT_INSERT]], 8 1743; CHECK-NEXT: [[A_SROA_5_4_EXTRACT_TRUNC:%.*]] = trunc i32 [[A_SROA_5_4_EXTRACT_SHIFT]] to i24 1744; CHECK-NEXT: ret void 1745; 1746entry: 1747 %a = alloca i64 1748 store volatile i16 42, ptr %a 1749 %load = load i32, ptr %a 1750 store i32 %load, ptr %a 1751 %a.gep1 = getelementptr i32, ptr %a, i32 1 1752 store volatile i8 13, ptr %a.gep1 1753 store i32 %load, ptr %a.gep1 1754 ret void 1755} 1756 1757define void @PR23737() { 1758; CHECK-LABEL: @PR23737( 1759; CHECK-NEXT: entry: 1760; CHECK-NEXT: [[PTR:%.*]] = alloca i64, align 8 1761; CHECK-NEXT: store atomic volatile i64 0, ptr [[PTR]] seq_cst, align 8 1762; CHECK-NEXT: [[PTR_0_LOAD:%.*]] = load atomic volatile i64, ptr [[PTR]] seq_cst, align 8 1763; CHECK-NEXT: ret void 1764; 1765entry: 1766 %ptr = alloca i64, align 8 1767 store atomic volatile i64 0, ptr %ptr seq_cst, align 8 1768 %load = load atomic volatile i64, ptr %ptr seq_cst, align 8 1769 ret void 1770} 1771 1772define i16 @PR24463() { 1773; Ensure we can handle a very interesting case where there is an integer-based 1774; rewrite of the uses of the alloca, but where one of the integers in that is 1775; a sub-integer that requires extraction *and* extends past the end of the 1776; alloca. SROA can split the alloca to avoid shift or trunc. 1777; 1778; 1779; CHECK-LABEL: @PR24463( 1780; CHECK-NEXT: entry: 1781; CHECK-NEXT: [[ALLOCA_SROA_1_2_LOAD_EXT:%.*]] = zext i8 0 to i16 1782; CHECK-NEXT: ret i16 [[ALLOCA_SROA_1_2_LOAD_EXT]] 1783; 1784entry: 1785 %alloca = alloca [3 x i8] 1786 %gep1 = getelementptr inbounds [3 x i8], ptr %alloca, i64 0, i64 1 1787 store i16 0, ptr %gep1 1788 %gep2 = getelementptr inbounds [3 x i8], ptr %alloca, i64 0, i64 2 1789 %load = load i16, ptr %gep2 1790 ret i16 %load 1791} 1792 1793%struct.STest = type { %struct.SPos, %struct.SPos } 1794%struct.SPos = type { float, float } 1795 1796define void @PR25873(ptr %outData) { 1797; CHECK-LABEL: @PR25873( 1798; CHECK-NEXT: entry: 1799; CHECK-NEXT: store i32 1123418112, ptr [[OUTDATA:%.*]], align 4 1800; CHECK-NEXT: [[OUTDATA_SROA_IDX:%.*]] = getelementptr inbounds i8, ptr [[OUTDATA]], i64 4 1801; CHECK-NEXT: store i32 1139015680, ptr [[OUTDATA_SROA_IDX]], align 4 1802; CHECK-NEXT: [[TMPDATA_SROA_6_0_OUTDATA_SROA_IDX:%.*]] = getelementptr inbounds i8, ptr [[OUTDATA]], i64 8 1803; CHECK-NEXT: [[TMPDATA_SROA_6_SROA_4_0_INSERT_EXT:%.*]] = zext i32 1139015680 to i64 1804; CHECK-NEXT: [[TMPDATA_SROA_6_SROA_4_0_INSERT_SHIFT:%.*]] = shl i64 [[TMPDATA_SROA_6_SROA_4_0_INSERT_EXT]], 32 1805; CHECK-NEXT: [[TMPDATA_SROA_6_SROA_4_0_INSERT_MASK:%.*]] = and i64 undef, 4294967295 1806; CHECK-NEXT: [[TMPDATA_SROA_6_SROA_4_0_INSERT_INSERT:%.*]] = or i64 [[TMPDATA_SROA_6_SROA_4_0_INSERT_MASK]], [[TMPDATA_SROA_6_SROA_4_0_INSERT_SHIFT]] 1807; CHECK-NEXT: [[TMPDATA_SROA_6_SROA_0_0_INSERT_EXT:%.*]] = zext i32 1123418112 to i64 1808; CHECK-NEXT: [[TMPDATA_SROA_6_SROA_0_0_INSERT_MASK:%.*]] = and i64 [[TMPDATA_SROA_6_SROA_4_0_INSERT_INSERT]], -4294967296 1809; CHECK-NEXT: [[TMPDATA_SROA_6_SROA_0_0_INSERT_INSERT:%.*]] = or i64 [[TMPDATA_SROA_6_SROA_0_0_INSERT_MASK]], [[TMPDATA_SROA_6_SROA_0_0_INSERT_EXT]] 1810; CHECK-NEXT: store i64 [[TMPDATA_SROA_6_SROA_0_0_INSERT_INSERT]], ptr [[TMPDATA_SROA_6_0_OUTDATA_SROA_IDX]], align 4 1811; CHECK-NEXT: ret void 1812; 1813entry: 1814 %tmpData = alloca %struct.STest, align 8 1815 call void @llvm.lifetime.start.p0(i64 16, ptr %tmpData) 1816 store float 1.230000e+02, ptr %tmpData, align 8 1817 %y = getelementptr inbounds %struct.STest, ptr %tmpData, i64 0, i32 0, i32 1 1818 store float 4.560000e+02, ptr %y, align 4 1819 %m_posB = getelementptr inbounds %struct.STest, ptr %tmpData, i64 0, i32 1 1820 %0 = load i64, ptr %tmpData, align 8 1821 store i64 %0, ptr %m_posB, align 8 1822 call void @llvm.memcpy.p0.p0.i64(ptr align 4 %outData, ptr align 4 %tmpData, i64 16, i1 false) 1823 call void @llvm.lifetime.end.p0(i64 16, ptr %tmpData) 1824 ret void 1825} 1826 1827declare void @llvm.memcpy.p0.p0.i64(ptr nocapture, ptr nocapture, i64, i1) nounwind 1828 1829define void @PR27999() unnamed_addr { 1830; CHECK-LABEL: @PR27999( 1831; CHECK-NEXT: entry-block: 1832; CHECK-NEXT: ret void 1833; 1834entry-block: 1835 %0 = alloca [2 x i64], align 8 1836 call void @llvm.lifetime.start.p0(i64 16, ptr %0) 1837 %1 = getelementptr inbounds [2 x i64], ptr %0, i32 0, i32 1 1838 call void @llvm.lifetime.end.p0(i64 8, ptr %1) 1839 ret void 1840} 1841 1842define void @PR29139() { 1843; CHECK-LABEL: @PR29139( 1844; CHECK-NEXT: bb1: 1845; CHECK-NEXT: ret void 1846; 1847bb1: 1848 %e.7.sroa.6.i = alloca i32, align 1 1849 %e.7.sroa.6.0.load81.i = load i32, ptr %e.7.sroa.6.i, align 1 1850 call void @llvm.lifetime.end.p0(i64 2, ptr %e.7.sroa.6.i) 1851 ret void 1852} 1853 1854; PR35657 reports assertion failure with this code 1855define void @PR35657(i64 %v) { 1856; CHECK-LABEL: @PR35657( 1857; CHECK-NEXT: entry: 1858; CHECK-NEXT: [[A48_SROA_0_0_EXTRACT_TRUNC:%.*]] = trunc i64 [[V:%.*]] to i16 1859; CHECK-NEXT: [[A48_SROA_2_0_EXTRACT_SHIFT:%.*]] = lshr i64 [[V]], 16 1860; CHECK-NEXT: [[A48_SROA_2_0_EXTRACT_TRUNC:%.*]] = trunc i64 [[A48_SROA_2_0_EXTRACT_SHIFT]] to i48 1861; CHECK-NEXT: call void @callee16(i16 [[A48_SROA_0_0_EXTRACT_TRUNC]]) 1862; CHECK-NEXT: call void @callee48(i48 [[A48_SROA_2_0_EXTRACT_TRUNC]]) 1863; CHECK-NEXT: ret void 1864; 1865entry: 1866 %a48 = alloca i48 1867 store i64 %v, ptr %a48 1868 %b0_15 = load i16, ptr %a48 1869 %a48_offset2 = getelementptr inbounds i8, ptr %a48, i64 2 1870 %b16_63 = load i48, ptr %a48_offset2, align 2 1871 call void @callee16(i16 %b0_15) 1872 call void @callee48(i48 %b16_63) 1873 ret void 1874} 1875 1876declare void @callee16(i16 %a) 1877declare void @callee48(i48 %a) 1878 1879define void @test28(i64 %v) #0 { 1880; SROA should split the first i64 store to avoid additional and/or instructions 1881; when storing into i32 fields 1882; 1883; CHECK-LABEL: @test28( 1884; CHECK-NEXT: entry: 1885; CHECK-NEXT: [[T_SROA_0_8_EXTRACT_TRUNC:%.*]] = trunc i64 [[V:%.*]] to i32 1886; CHECK-NEXT: [[T_SROA_2_8_EXTRACT_SHIFT:%.*]] = lshr i64 [[V]], 32 1887; CHECK-NEXT: [[T_SROA_2_8_EXTRACT_TRUNC:%.*]] = trunc i64 [[T_SROA_2_8_EXTRACT_SHIFT]] to i32 1888; CHECK-NEXT: ret void 1889; 1890entry: 1891 %t = alloca { i64, i32, i32 } 1892 1893 %b = getelementptr { i64, i32, i32 }, ptr %t, i32 0, i32 1 1894 store i64 %v, ptr %b 1895 1896 %0 = load i32, ptr %b 1897 %c = getelementptr { i64, i32, i32 }, ptr %t, i32 0, i32 2 1898 store i32 %0, ptr %c 1899 ret void 1900} 1901 1902declare void @llvm.lifetime.start.isVoid.i64.p0(i64, ptr nocapture) 1903declare void @llvm.lifetime.end.isVoid.i64.p0(i64, ptr nocapture) 1904@array = dso_local global [10 x float] zeroinitializer, align 4 1905 1906define void @test29(i32 %num, i32 %tid) { 1907; CHECK-LABEL: @test29( 1908; CHECK-NEXT: entry: 1909; CHECK-NEXT: [[CMP1:%.*]] = icmp sgt i32 [[NUM:%.*]], 0 1910; CHECK-NEXT: br i1 [[CMP1]], label [[BB1:%.*]], label [[BB7:%.*]] 1911; CHECK: bb1: 1912; CHECK-NEXT: [[TOBOOL:%.*]] = icmp eq i32 [[TID:%.*]], 0 1913; CHECK-NEXT: [[CONV_I:%.*]] = zext i32 [[TID]] to i64 1914; CHECK-NEXT: [[ARRAYIDX5:%.*]] = getelementptr inbounds [10 x float], ptr @array, i64 0, i64 [[CONV_I]] 1915; CHECK-NEXT: br label [[BB2:%.*]] 1916; CHECK: bb2: 1917; CHECK-NEXT: [[I_02:%.*]] = phi i32 [ [[NUM]], [[BB1]] ], [ [[SUB:%.*]], [[BB5:%.*]] ] 1918; CHECK-NEXT: br i1 [[TOBOOL]], label [[BB3:%.*]], label [[BB4:%.*]] 1919; CHECK: bb3: 1920; CHECK-NEXT: br label [[BB5]] 1921; CHECK: bb4: 1922; CHECK-NEXT: store i32 undef, ptr [[ARRAYIDX5]], align 4 1923; CHECK-NEXT: br label [[BB5]] 1924; CHECK: bb5: 1925; CHECK-NEXT: [[SUB]] = add i32 [[I_02]], -1 1926; CHECK-NEXT: [[CMP:%.*]] = icmp sgt i32 [[SUB]], 0 1927; CHECK-NEXT: br i1 [[CMP]], label [[BB2]], label [[BB6:%.*]] 1928; CHECK: bb6: 1929; CHECK-NEXT: br label [[BB7]] 1930; CHECK: bb7: 1931; CHECK-NEXT: ret void 1932; 1933entry: 1934 %ra = alloca [10 x float], align 4 1935 call void @llvm.lifetime.start.isVoid.i64.p0(i64 40, ptr nonnull %ra) 1936 1937 %cmp1 = icmp sgt i32 %num, 0 1938 br i1 %cmp1, label %bb1, label %bb7 1939 1940bb1: 1941 %tobool = icmp eq i32 %tid, 0 1942 %conv.i = zext i32 %tid to i64 1943 %0 = load i32, ptr %ra, align 4 1944 %arrayidx5 = getelementptr inbounds [10 x float], ptr @array, i64 0, i64 %conv.i 1945 br label %bb2 1946 1947bb2: 1948 %i.02 = phi i32 [ %num, %bb1 ], [ %sub, %bb5 ] 1949 br i1 %tobool, label %bb3, label %bb4 1950 1951bb3: 1952 br label %bb5 1953 1954bb4: 1955 store i32 %0, ptr %arrayidx5, align 4 1956 br label %bb5 1957 1958bb5: 1959 %sub = add i32 %i.02, -1 1960 %cmp = icmp sgt i32 %sub, 0 1961 br i1 %cmp, label %bb2, label %bb6 1962 1963bb6: 1964 br label %bb7 1965 1966bb7: 1967 call void @llvm.lifetime.end.isVoid.i64.p0(i64 40, ptr nonnull %ra) 1968 ret void 1969} 1970 1971define i32 @load_atomic_volatile_past_end() { 1972; CHECK-LABEL: @load_atomic_volatile_past_end( 1973; CHECK-NEXT: [[A:%.*]] = alloca i1, align 1 1974; CHECK-NEXT: [[A_0_V:%.*]] = load atomic volatile i32, ptr [[A]] seq_cst, align 1 1975; CHECK-NEXT: ret i32 [[A_0_V]] 1976; 1977 %a = alloca i1, align 1 1978 %v = load atomic volatile i32, ptr %a seq_cst, align 4 1979 ret i32 %v 1980} 1981 1982define i32 @load_volatile_past_end() { 1983; CHECK-LABEL: @load_volatile_past_end( 1984; CHECK-NEXT: [[A:%.*]] = alloca i1, align 1 1985; CHECK-NEXT: [[A_0_V:%.*]] = load volatile i32, ptr [[A]], align 1 1986; CHECK-NEXT: ret i32 [[A_0_V]] 1987; 1988 %a = alloca i1, align 1 1989 %v = load volatile i32, ptr %a, align 4 1990 ret i32 %v 1991} 1992 1993define i32 @load_atomic_past_end() { 1994; CHECK-LABEL: @load_atomic_past_end( 1995; CHECK-NEXT: [[A_0_LOAD_EXT:%.*]] = zext i1 undef to i32 1996; CHECK-NEXT: ret i32 [[A_0_LOAD_EXT]] 1997; 1998 %a = alloca i1, align 1 1999 %v = load atomic i32, ptr %a seq_cst, align 4 2000 ret i32 %v 2001} 2002 2003!0 = !{!1, !1, i64 0, i64 200} 2004!1 = !{!2, i64 1, !"type_0"} 2005!2 = !{!"root"} 2006!3 = !{!4, !4, i64 0, i64 1} 2007!4 = !{!2, i64 1, !"type_3"} 2008!5 = !{!6, !6, i64 0, i64 1} 2009!6 = !{!2, i64 1, !"type_5"} 2010!7 = !{!8, !8, i64 0, i64 1} 2011!8 = !{!2, i64 1, !"type_7"} 2012!9 = !{!10, !10, i64 0, i64 1} 2013!10 = !{!2, i64 1, !"type_9"} 2014!11 = !{!12, !12, i64 0, i64 1} 2015!12 = !{!2, i64 1, !"type_11"} 2016!13 = !{!14, !14, i64 0, i64 1} 2017!14 = !{!2, i64 1, !"type_13"} 2018!15 = !{!16, !16, i64 0, i64 1} 2019!16 = !{!2, i64 1, !"type_15"} 2020!17 = !{!18, !18, i64 0, i64 1} 2021!18 = !{!2, i64 1, !"type_17"} 2022!19 = !{!20, !20, i64 0, i64 1} 2023!20 = !{!2, i64 1, !"type_19"} 2024!21 = !{!22, !22, i64 0, i64 1} 2025!22 = !{!2, i64 1, !"type_21"} 2026!23 = !{!24, !24, i64 0, i64 1} 2027!24 = !{!2, i64 1, !"type_23"} 2028!25 = !{!26, !26, i64 0, i64 1} 2029!26 = !{!2, i64 1, !"type_25"} 2030!27 = !{!28, !28, i64 0, i64 1} 2031!28 = !{!2, i64 1, !"type_27"} 2032!29 = !{!30, !30, i64 0, i64 1} 2033!30 = !{!2, i64 1, !"type_29"} 2034!31 = !{!32, !32, i64 0, i64 1} 2035!32 = !{!2, i64 1, !"type_31"} 2036!33 = !{!34, !34, i64 0, i64 1} 2037!34 = !{!2, i64 1, !"type_33"} 2038!35 = !{!36, !36, i64 0, i64 1} 2039!36 = !{!2, i64 1, !"type_35"} 2040!37 = !{!38, !38, i64 0, i64 1} 2041!38 = !{!2, i64 1, !"type_37"} 2042!39 = !{!40, !40, i64 0, i64 1} 2043!40 = !{!2, i64 1, !"type_39"} 2044!41 = !{!42, !42, i64 0, i64 1} 2045!42 = !{!2, i64 1, !"type_41"} 2046!43 = !{!44, !44, i64 0, i64 1} 2047!44 = !{!2, i64 1, !"type_43"} 2048!45 = !{!46, !46, i64 0, i64 1} 2049!46 = !{!2, i64 1, !"type_45"} 2050!47 = !{!48, !48, i64 0, i64 1} 2051!48 = !{!2, i64 1, !"type_47"} 2052!49 = !{!50, !50, i64 0, i64 1} 2053!50 = !{!2, i64 1, !"type_49"} 2054!51 = !{!52, !52, i64 0, i64 1} 2055!52 = !{!2, i64 1, !"type_51"} 2056!53 = !{!54, !54, i64 0, i64 1} 2057!54 = !{!2, i64 1, !"type_53"} 2058!55 = !{!56, !56, i64 0, i64 1} 2059!56 = !{!2, i64 1, !"type_55"} 2060!57 = !{!58, !58, i64 0, i64 1} 2061!58 = !{!2, i64 1, !"type_57"} 2062!59 = !{!60, !60, i64 0, i64 1} 2063!60 = !{!2, i64 1, !"type_59"} 2064 2065 2066 2067 2068 2069 2070 2071 2072 2073 2074