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; RUN: opt -passes='debugify,function(sroa<preserve-cfg>)' -S < %s | FileCheck %s -check-prefix CHECK-DEBUGLOC 5; RUN: opt -passes='debugify,function(sroa<preserve-cfg>)' -S < %s --try-experimental-debuginfo-iterators | FileCheck %s -check-prefix CHECK-DEBUGLOC 6 7target datalayout = "e-p:64:64:64-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" 8 9declare void @llvm.memcpy.p0.p0.i32(ptr, ptr, i32, i1) 10 11define void @test1(ptr %a, ptr %b) { 12; CHECK-LABEL: @test1( 13; CHECK-NEXT: entry: 14; CHECK-NEXT: [[GEP_A:%.*]] = getelementptr { i8, i8 }, ptr [[A:%.*]], i32 0, i32 0 15; CHECK-NEXT: [[GEP_B:%.*]] = getelementptr { i8, i8 }, ptr [[B:%.*]], i32 0, i32 0 16; CHECK-NEXT: [[ALLOCA_SROA_0_0_COPYLOAD:%.*]] = load i8, ptr [[GEP_A]], align 16 17; CHECK-NEXT: [[ALLOCA_SROA_3_0_GEP_A_SROA_IDX:%.*]] = getelementptr inbounds i8, ptr [[GEP_A]], i64 1 18; CHECK-NEXT: [[ALLOCA_SROA_3_0_COPYLOAD:%.*]] = load i8, ptr [[ALLOCA_SROA_3_0_GEP_A_SROA_IDX]], align 1 19; CHECK-NEXT: store i8 [[ALLOCA_SROA_0_0_COPYLOAD]], ptr [[GEP_B]], align 16 20; CHECK-NEXT: [[ALLOCA_SROA_3_0_GEP_B_SROA_IDX:%.*]] = getelementptr inbounds i8, ptr [[GEP_B]], i64 1 21; CHECK-NEXT: store i8 [[ALLOCA_SROA_3_0_COPYLOAD]], ptr [[ALLOCA_SROA_3_0_GEP_B_SROA_IDX]], align 1 22; CHECK-NEXT: ret void 23; 24; CHECK-DEBUGLOC-LABEL: @test1( 25; CHECK-DEBUGLOC-NEXT: entry: 26; CHECK-DEBUGLOC-NEXT: #dbg_value(ptr undef, [[META9:![0-9]+]], !DIExpression(DW_OP_LLVM_fragment, 0, 8), [[META14:![0-9]+]]) 27; CHECK-DEBUGLOC-NEXT: #dbg_value(ptr undef, [[META9]], !DIExpression(DW_OP_LLVM_fragment, 8, 8), [[META14]]) 28; CHECK-DEBUGLOC-NEXT: #dbg_value(ptr undef, [[META9]], !DIExpression(), [[META14]]) 29; CHECK-DEBUGLOC-NEXT: [[GEP_A:%.*]] = getelementptr { i8, i8 }, ptr [[A:%.*]], i32 0, i32 0, !dbg [[DBG15:![0-9]+]] 30; CHECK-DEBUGLOC-NEXT: #dbg_value(ptr [[GEP_A]], [[META11:![0-9]+]], !DIExpression(), [[DBG15]]) 31; CHECK-DEBUGLOC-NEXT: #dbg_value(ptr undef, [[META12:![0-9]+]], !DIExpression(), [[META16:![0-9]+]]) 32; CHECK-DEBUGLOC-NEXT: [[GEP_B:%.*]] = getelementptr { i8, i8 }, ptr [[B:%.*]], i32 0, i32 0, !dbg [[DBG17:![0-9]+]] 33; CHECK-DEBUGLOC-NEXT: #dbg_value(ptr [[GEP_B]], [[META13:![0-9]+]], !DIExpression(), [[DBG17]]) 34; CHECK-DEBUGLOC-NEXT: [[ALLOCA_SROA_0_0_COPYLOAD:%.*]] = load i8, ptr [[GEP_A]], align 16, !dbg [[DBG18:![0-9]+]] 35; CHECK-DEBUGLOC-NEXT: [[ALLOCA_SROA_3_0_GEP_A_SROA_IDX:%.*]] = getelementptr inbounds i8, ptr [[GEP_A]], i64 1, !dbg [[DBG18]] 36; CHECK-DEBUGLOC-NEXT: [[ALLOCA_SROA_3_0_COPYLOAD:%.*]] = load i8, ptr [[ALLOCA_SROA_3_0_GEP_A_SROA_IDX]], align 1, !dbg [[DBG18]] 37; CHECK-DEBUGLOC-NEXT: store i8 [[ALLOCA_SROA_0_0_COPYLOAD]], ptr [[GEP_B]], align 16, !dbg [[DBG19:![0-9]+]] 38; CHECK-DEBUGLOC-NEXT: [[ALLOCA_SROA_3_0_GEP_B_SROA_IDX:%.*]] = getelementptr inbounds i8, ptr [[GEP_B]], i64 1, !dbg [[DBG19]] 39; CHECK-DEBUGLOC-NEXT: store i8 [[ALLOCA_SROA_3_0_COPYLOAD]], ptr [[ALLOCA_SROA_3_0_GEP_B_SROA_IDX]], align 1, !dbg [[DBG19]] 40; CHECK-DEBUGLOC-NEXT: ret void, !dbg [[DBG20:![0-9]+]] 41; 42entry: 43 %alloca = alloca { i8, i8 }, align 16 44 %gep_a = getelementptr { i8, i8 }, ptr %a, i32 0, i32 0 45 %gep_alloca = getelementptr { i8, i8 }, ptr %alloca, i32 0, i32 0 46 %gep_b = getelementptr { i8, i8 }, ptr %b, i32 0, i32 0 47 48 store i8 420, ptr %gep_alloca, align 16 49 50 call void @llvm.memcpy.p0.p0.i32(ptr align 16 %gep_alloca, ptr align 16 %gep_a, i32 2, i1 false) 51 call void @llvm.memcpy.p0.p0.i32(ptr align 16 %gep_b, ptr align 16 %gep_alloca, i32 2, i1 false) 52 ret void 53} 54 55define void @test2() { 56; Check that when sroa rewrites the alloca partition 57; it preserves the original debuglocation. 58; CHECK-LABEL: @test2( 59; CHECK-NEXT: entry: 60; CHECK-NEXT: [[A_SROA_0:%.*]] = alloca i16, align 2 61; CHECK-NEXT: store volatile i16 0, ptr [[A_SROA_0]], align 2 62; CHECK-NEXT: [[A_SROA_0_1_GEP2_SROA_IDX:%.*]] = getelementptr inbounds i8, ptr [[A_SROA_0]], i64 1 63; CHECK-NEXT: [[A_SROA_0_1_A_SROA_0_2_RESULT:%.*]] = load i8, ptr [[A_SROA_0_1_GEP2_SROA_IDX]], align 1 64; CHECK-NEXT: [[A_SROA_0_1_GEP2_SROA_IDX2:%.*]] = getelementptr inbounds i8, ptr [[A_SROA_0]], i64 1 65; CHECK-NEXT: store i8 42, ptr [[A_SROA_0_1_GEP2_SROA_IDX2]], align 1 66; CHECK-NEXT: ret void 67; 68; CHECK-DEBUGLOC-LABEL: @test2( 69; CHECK-DEBUGLOC-NEXT: entry: 70; CHECK-DEBUGLOC-NEXT: [[A_SROA_0:%.*]] = alloca i16, align 2, !dbg [[DBG28:![0-9]+]] 71; CHECK-DEBUGLOC-NEXT: #dbg_value(ptr [[A_SROA_0]], [[META23:![0-9]+]], !DIExpression(DW_OP_LLVM_fragment, 8, 16), [[DBG28]]) 72; CHECK-DEBUGLOC-NEXT: #dbg_value(ptr undef, [[META23]], !DIExpression(), [[DBG28]]) 73; CHECK-DEBUGLOC-NEXT: #dbg_value(ptr undef, [[META24:![0-9]+]], !DIExpression(), [[META29:![0-9]+]]) 74; CHECK-DEBUGLOC-NEXT: store volatile i16 0, ptr [[A_SROA_0]], align 2, !dbg [[DBG30:![0-9]+]] 75; CHECK-DEBUGLOC-NEXT: #dbg_value(ptr undef, [[META25:![0-9]+]], !DIExpression(), [[META31:![0-9]+]]) 76; CHECK-DEBUGLOC-NEXT: [[A_SROA_0_1_GEP2_SROA_IDX:%.*]] = getelementptr inbounds i8, ptr [[A_SROA_0]], i64 1, !dbg [[DBG32:![0-9]+]] 77; CHECK-DEBUGLOC-NEXT: [[A_SROA_0_1_A_SROA_0_2_RESULT:%.*]] = load i8, ptr [[A_SROA_0_1_GEP2_SROA_IDX]], align 1, !dbg [[DBG32]] 78; CHECK-DEBUGLOC-NEXT: #dbg_value(i8 [[A_SROA_0_1_A_SROA_0_2_RESULT]], [[META26:![0-9]+]], !DIExpression(), [[DBG32]]) 79; CHECK-DEBUGLOC-NEXT: [[A_SROA_0_1_GEP2_SROA_IDX2:%.*]] = getelementptr inbounds i8, ptr [[A_SROA_0]], i64 1, !dbg [[DBG33:![0-9]+]] 80; CHECK-DEBUGLOC-NEXT: store i8 42, ptr [[A_SROA_0_1_GEP2_SROA_IDX2]], align 1, !dbg [[DBG33]] 81; CHECK-DEBUGLOC-NEXT: ret void, !dbg [[DBG34:![0-9]+]] 82; 83entry: 84 %a = alloca { i8, i8, i8, i8 }, align 2 ; "line 9" to -debugify 85 %gep1 = getelementptr { i8, i8, i8, i8 }, ptr %a, i32 0, i32 1 86 store volatile i16 0, ptr %gep1 87 %gep2 = getelementptr { i8, i8, i8, i8 }, ptr %a, i32 0, i32 2 88 %result = load i8, ptr %gep2 89 store i8 42, ptr %gep2 90 ret void 91} 92 93define void @PR13920(ptr %a, ptr %b) { 94; Test that alignments on memcpy intrinsics get propagated to loads and stores. 95; 96; 97; CHECK-LABEL: @PR13920( 98; CHECK-NEXT: entry: 99; CHECK-NEXT: [[AA_0_COPYLOAD:%.*]] = load <2 x i64>, ptr [[A:%.*]], align 2 100; CHECK-NEXT: store <2 x i64> [[AA_0_COPYLOAD]], ptr [[B:%.*]], align 2 101; CHECK-NEXT: ret void 102; 103; CHECK-DEBUGLOC-LABEL: @PR13920( 104; CHECK-DEBUGLOC-NEXT: entry: 105; CHECK-DEBUGLOC-NEXT: #dbg_value(ptr undef, [[META37:![0-9]+]], !DIExpression(), [[META38:![0-9]+]]) 106; CHECK-DEBUGLOC-NEXT: [[AA_0_COPYLOAD:%.*]] = load <2 x i64>, ptr [[A:%.*]], align 2, !dbg [[DBG39:![0-9]+]] 107; CHECK-DEBUGLOC-NEXT: store <2 x i64> [[AA_0_COPYLOAD]], ptr [[B:%.*]], align 2, !dbg [[DBG40:![0-9]+]] 108; CHECK-DEBUGLOC-NEXT: ret void, !dbg [[DBG41:![0-9]+]] 109; 110entry: 111 %aa = alloca <2 x i64>, align 16 112 call void @llvm.memcpy.p0.p0.i32(ptr align 2 %aa, ptr align 2 %a, i32 16, i1 false) 113 call void @llvm.memcpy.p0.p0.i32(ptr align 2 %b, ptr align 2 %aa, i32 16, i1 false) 114 ret void 115} 116 117define void @test3(ptr %x) { 118; Test that when we promote an alloca to a type with lower ABI alignment, we 119; provide the needed explicit alignment that code using the alloca may be 120; expecting. However, also check that any offset within an alloca can in turn 121; reduce the alignment. 122; 123; CHECK-LABEL: @test3( 124; CHECK-NEXT: entry: 125; CHECK-NEXT: [[A_SROA_0:%.*]] = alloca [22 x i8], align 8 126; CHECK-NEXT: [[B_SROA_0:%.*]] = alloca [18 x i8], align 2 127; CHECK-NEXT: call void @llvm.memcpy.p0.p0.i32(ptr align 8 [[A_SROA_0]], ptr align 8 [[X:%.*]], i32 22, i1 false) 128; CHECK-NEXT: call void @llvm.memcpy.p0.p0.i32(ptr align 2 [[B_SROA_0]], ptr align 2 [[X]], i32 18, i1 false) 129; CHECK-NEXT: ret void 130; 131; CHECK-DEBUGLOC-LABEL: @test3( 132; CHECK-DEBUGLOC-NEXT: entry: 133; CHECK-DEBUGLOC-NEXT: [[A_SROA_0:%.*]] = alloca [22 x i8], align 8, !dbg [[DBG47:![0-9]+]] 134; CHECK-DEBUGLOC-NEXT: #dbg_value(ptr [[A_SROA_0]], [[META44:![0-9]+]], !DIExpression(), [[DBG47]]) 135; CHECK-DEBUGLOC-NEXT: #dbg_value(ptr undef, [[META44]], !DIExpression(), [[DBG47]]) 136; CHECK-DEBUGLOC-NEXT: [[B_SROA_0:%.*]] = alloca [18 x i8], align 2, !dbg [[DBG48:![0-9]+]] 137; CHECK-DEBUGLOC-NEXT: #dbg_value(ptr [[B_SROA_0]], [[META45:![0-9]+]], !DIExpression(DW_OP_LLVM_fragment, 48, 16), [[DBG48]]) 138; CHECK-DEBUGLOC-NEXT: #dbg_value(ptr undef, [[META45]], !DIExpression(), [[DBG48]]) 139; CHECK-DEBUGLOC-NEXT: call void @llvm.memcpy.p0.p0.i32(ptr align 8 [[A_SROA_0]], ptr align 8 [[X:%.*]], i32 22, i1 false), !dbg [[DBG49:![0-9]+]] 140; CHECK-DEBUGLOC-NEXT: #dbg_value(ptr undef, [[META46:![0-9]+]], !DIExpression(), [[META50:![0-9]+]]) 141; CHECK-DEBUGLOC-NEXT: call void @llvm.memcpy.p0.p0.i32(ptr align 2 [[B_SROA_0]], ptr align 2 [[X]], i32 18, i1 false), !dbg [[DBG51:![0-9]+]] 142; CHECK-DEBUGLOC-NEXT: ret void, !dbg [[DBG52:![0-9]+]] 143; 144entry: 145 %a = alloca { ptr, ptr, ptr } 146 %b = alloca { ptr, ptr, ptr } 147 call void @llvm.memcpy.p0.p0.i32(ptr align 8 %a, ptr align 8 %x, i32 22, i1 false) 148 %b_gep = getelementptr i8, ptr %b, i32 6 149 call void @llvm.memcpy.p0.p0.i32(ptr align 2 %b_gep, ptr align 2 %x, i32 18, i1 false) 150 ret void 151} 152 153define void @test5() { 154; Test that we preserve underaligned loads and stores when splitting. The use 155; of volatile in this test case is just to force the loads and stores to not be 156; split or promoted out of existence. 157; 158; 159; 160; CHECK-LABEL: @test5( 161; CHECK-NEXT: entry: 162; CHECK-NEXT: [[A_SROA_0:%.*]] = alloca [9 x i8], align 1 163; CHECK-NEXT: [[A_SROA_3:%.*]] = alloca [9 x i8], align 1 164; CHECK-NEXT: store volatile double 0.000000e+00, ptr [[A_SROA_0]], align 1 165; CHECK-NEXT: [[A_SROA_0_7_WEIRD_GEP1_SROA_IDX1:%.*]] = getelementptr inbounds i8, ptr [[A_SROA_0]], i64 7 166; CHECK-NEXT: [[A_SROA_0_7_A_SROA_0_7_WEIRD_LOAD1:%.*]] = load volatile i16, ptr [[A_SROA_0_7_WEIRD_GEP1_SROA_IDX1]], align 1 167; CHECK-NEXT: [[A_SROA_0_0_A_SROA_0_0_D1:%.*]] = load double, ptr [[A_SROA_0]], align 1 168; CHECK-NEXT: store volatile double [[A_SROA_0_0_A_SROA_0_0_D1]], ptr [[A_SROA_3]], align 1 169; CHECK-NEXT: [[A_SROA_3_7_WEIRD_GEP2_SROA_IDX:%.*]] = getelementptr inbounds i8, ptr [[A_SROA_3]], i64 7 170; CHECK-NEXT: [[A_SROA_3_7_A_SROA_3_16_WEIRD_LOAD2:%.*]] = load volatile i16, ptr [[A_SROA_3_7_WEIRD_GEP2_SROA_IDX]], align 1 171; CHECK-NEXT: ret void 172; 173; CHECK-DEBUGLOC-LABEL: @test5( 174; CHECK-DEBUGLOC-NEXT: entry: 175; CHECK-DEBUGLOC-NEXT: [[A_SROA_0:%.*]] = alloca [9 x i8], align 1, !dbg [[DBG63:![0-9]+]] 176; CHECK-DEBUGLOC-NEXT: [[A_SROA_3:%.*]] = alloca [9 x i8], align 1, !dbg [[DBG63]] 177; CHECK-DEBUGLOC-NEXT: #dbg_value(ptr [[A_SROA_0]], [[META55:![0-9]+]], !DIExpression(), [[DBG63]]) 178; CHECK-DEBUGLOC-NEXT: #dbg_value(ptr undef, [[META55]], !DIExpression(), [[DBG63]]) 179; CHECK-DEBUGLOC-NEXT: store volatile double 0.000000e+00, ptr [[A_SROA_0]], align 1, !dbg [[DBG64:![0-9]+]] 180; CHECK-DEBUGLOC-NEXT: #dbg_value(ptr undef, [[META56:![0-9]+]], !DIExpression(), [[META65:![0-9]+]]) 181; CHECK-DEBUGLOC-NEXT: [[A_SROA_0_7_WEIRD_GEP1_SROA_IDX1:%.*]] = getelementptr inbounds i8, ptr [[A_SROA_0]], i64 7, !dbg [[DBG66:![0-9]+]] 182; CHECK-DEBUGLOC-NEXT: [[A_SROA_0_7_A_SROA_0_7_WEIRD_LOAD1:%.*]] = load volatile i16, ptr [[A_SROA_0_7_WEIRD_GEP1_SROA_IDX1]], align 1, !dbg [[DBG66]] 183; CHECK-DEBUGLOC-NEXT: #dbg_value(i16 [[A_SROA_0_7_A_SROA_0_7_WEIRD_LOAD1]], [[META57:![0-9]+]], !DIExpression(), [[DBG66]]) 184; CHECK-DEBUGLOC-NEXT: #dbg_value(ptr undef, [[META59:![0-9]+]], !DIExpression(), [[META67:![0-9]+]]) 185; CHECK-DEBUGLOC-NEXT: [[A_SROA_0_0_A_SROA_0_0_D1:%.*]] = load double, ptr [[A_SROA_0]], align 1, !dbg [[DBG68:![0-9]+]] 186; CHECK-DEBUGLOC-NEXT: #dbg_value(double [[A_SROA_0_0_A_SROA_0_0_D1]], [[META60:![0-9]+]], !DIExpression(), [[DBG68]]) 187; CHECK-DEBUGLOC-NEXT: store volatile double [[A_SROA_0_0_A_SROA_0_0_D1]], ptr [[A_SROA_3]], align 1, !dbg [[DBG69:![0-9]+]] 188; CHECK-DEBUGLOC-NEXT: #dbg_value(ptr undef, [[META61:![0-9]+]], !DIExpression(), [[META70:![0-9]+]]) 189; CHECK-DEBUGLOC-NEXT: [[A_SROA_3_7_WEIRD_GEP2_SROA_IDX:%.*]] = getelementptr inbounds i8, ptr [[A_SROA_3]], i64 7, !dbg [[DBG71:![0-9]+]] 190; CHECK-DEBUGLOC-NEXT: [[A_SROA_3_7_A_SROA_3_16_WEIRD_LOAD2:%.*]] = load volatile i16, ptr [[A_SROA_3_7_WEIRD_GEP2_SROA_IDX]], align 1, !dbg [[DBG71]] 191; CHECK-DEBUGLOC-NEXT: #dbg_value(i16 [[A_SROA_3_7_A_SROA_3_16_WEIRD_LOAD2]], [[META62:![0-9]+]], !DIExpression(), [[DBG71]]) 192; CHECK-DEBUGLOC-NEXT: ret void, !dbg [[DBG72:![0-9]+]] 193; 194entry: 195 %a = alloca [18 x i8] 196 store volatile double 0.0, ptr %a, align 1 197 %weird_gep1 = getelementptr inbounds [18 x i8], ptr %a, i32 0, i32 7 198 %weird_load1 = load volatile i16, ptr %weird_gep1, align 1 199 200 %raw2 = getelementptr inbounds [18 x i8], ptr %a, i32 0, i32 9 201 %d1 = load double, ptr %a, align 1 202 store volatile double %d1, ptr %raw2, align 1 203 %weird_gep2 = getelementptr inbounds [18 x i8], ptr %a, i32 0, i32 16 204 %weird_load2 = load volatile i16, ptr %weird_gep2, align 1 205 206 ret void 207} 208 209define void @test6() { 210; We should set the alignment on all load and store operations; make sure 211; we choose an appropriate alignment. 212; 213; 214; CHECK-LABEL: @test6( 215; CHECK-NEXT: entry: 216; CHECK-NEXT: [[A_SROA_0:%.*]] = alloca double, align 8 217; CHECK-NEXT: [[A_SROA_2:%.*]] = alloca double, align 8 218; CHECK-NEXT: store volatile double 0.000000e+00, ptr [[A_SROA_0]], align 8 219; CHECK-NEXT: [[A_SROA_0_0_A_SROA_0_0_VAL:%.*]] = load double, ptr [[A_SROA_0]], align 8 220; CHECK-NEXT: store volatile double [[A_SROA_0_0_A_SROA_0_0_VAL]], ptr [[A_SROA_2]], align 8 221; CHECK-NEXT: ret void 222; 223; CHECK-DEBUGLOC-LABEL: @test6( 224; CHECK-DEBUGLOC-NEXT: entry: 225; CHECK-DEBUGLOC-NEXT: [[A_SROA_0:%.*]] = alloca double, align 8, !dbg [[DBG78:![0-9]+]] 226; CHECK-DEBUGLOC-NEXT: [[A_SROA_2:%.*]] = alloca double, align 8, !dbg [[DBG78]] 227; CHECK-DEBUGLOC-NEXT: #dbg_value(ptr [[A_SROA_0]], [[META75:![0-9]+]], !DIExpression(), [[DBG78]]) 228; CHECK-DEBUGLOC-NEXT: #dbg_value(ptr undef, [[META75]], !DIExpression(), [[DBG78]]) 229; CHECK-DEBUGLOC-NEXT: store volatile double 0.000000e+00, ptr [[A_SROA_0]], align 8, !dbg [[DBG79:![0-9]+]] 230; CHECK-DEBUGLOC-NEXT: #dbg_value(ptr undef, [[META76:![0-9]+]], !DIExpression(), [[META80:![0-9]+]]) 231; CHECK-DEBUGLOC-NEXT: [[A_SROA_0_0_A_SROA_0_0_VAL:%.*]] = load double, ptr [[A_SROA_0]], align 8, !dbg [[DBG81:![0-9]+]] 232; CHECK-DEBUGLOC-NEXT: #dbg_value(double [[A_SROA_0_0_A_SROA_0_0_VAL]], [[META77:![0-9]+]], !DIExpression(), [[DBG81]]) 233; CHECK-DEBUGLOC-NEXT: store volatile double [[A_SROA_0_0_A_SROA_0_0_VAL]], ptr [[A_SROA_2]], align 8, !dbg [[DBG82:![0-9]+]] 234; CHECK-DEBUGLOC-NEXT: ret void, !dbg [[DBG83:![0-9]+]] 235; 236entry: 237 %a = alloca [16 x i8] 238 store volatile double 0.0, ptr %a, align 1 239 240 %raw2 = getelementptr inbounds [16 x i8], ptr %a, i32 0, i32 8 241 %val = load double, ptr %a, align 1 242 store volatile double %val, ptr %raw2, align 1 243 244 ret void 245} 246 247define void @test7(ptr %out) { 248; Test that we properly compute the destination alignment when rewriting 249; memcpys as direct loads or stores. 250; 251; 252; CHECK-LABEL: @test7( 253; CHECK-NEXT: entry: 254; CHECK-NEXT: [[A_SROA_0_0_COPYLOAD:%.*]] = load double, ptr [[OUT:%.*]], align 1 255; CHECK-NEXT: [[A_SROA_4_0_OUT_SROA_IDX:%.*]] = getelementptr inbounds i8, ptr [[OUT]], i64 8 256; CHECK-NEXT: [[A_SROA_4_0_COPYLOAD:%.*]] = load double, ptr [[A_SROA_4_0_OUT_SROA_IDX]], align 1 257; CHECK-NEXT: store double [[A_SROA_4_0_COPYLOAD]], ptr [[OUT]], align 1 258; CHECK-NEXT: [[A_SROA_4_0_OUT_SROA_IDX2:%.*]] = getelementptr inbounds i8, ptr [[OUT]], i64 8 259; CHECK-NEXT: store double [[A_SROA_0_0_COPYLOAD]], ptr [[A_SROA_4_0_OUT_SROA_IDX2]], align 1 260; CHECK-NEXT: ret void 261; 262; CHECK-DEBUGLOC-LABEL: @test7( 263; CHECK-DEBUGLOC-NEXT: entry: 264; CHECK-DEBUGLOC-NEXT: #dbg_value(ptr undef, [[META86:![0-9]+]], !DIExpression(), [[META90:![0-9]+]]) 265; CHECK-DEBUGLOC-NEXT: #dbg_value(ptr undef, [[META86]], !DIExpression(), [[META90]]) 266; CHECK-DEBUGLOC-NEXT: #dbg_value(ptr undef, [[META87:![0-9]+]], !DIExpression(), [[META91:![0-9]+]]) 267; CHECK-DEBUGLOC-NEXT: [[A_SROA_0_0_COPYLOAD:%.*]] = load double, ptr [[OUT:%.*]], align 1, !dbg [[DBG92:![0-9]+]] 268; CHECK-DEBUGLOC-NEXT: [[A_SROA_4_0_OUT_SROA_IDX:%.*]] = getelementptr inbounds i8, ptr [[OUT]], i64 8, !dbg [[DBG92]] 269; CHECK-DEBUGLOC-NEXT: [[A_SROA_4_0_COPYLOAD:%.*]] = load double, ptr [[A_SROA_4_0_OUT_SROA_IDX]], align 1, !dbg [[DBG92]] 270; CHECK-DEBUGLOC-NEXT: #dbg_value(double [[A_SROA_4_0_COPYLOAD]], [[META88:![0-9]+]], !DIExpression(), [[META93:![0-9]+]]) 271; CHECK-DEBUGLOC-NEXT: #dbg_value(double [[A_SROA_0_0_COPYLOAD]], [[META89:![0-9]+]], !DIExpression(), [[META94:![0-9]+]]) 272; CHECK-DEBUGLOC-NEXT: store double [[A_SROA_4_0_COPYLOAD]], ptr [[OUT]], align 1, !dbg [[DBG95:![0-9]+]] 273; CHECK-DEBUGLOC-NEXT: [[A_SROA_4_0_OUT_SROA_IDX2:%.*]] = getelementptr inbounds i8, ptr [[OUT]], i64 8, !dbg [[DBG95]] 274; CHECK-DEBUGLOC-NEXT: store double [[A_SROA_0_0_COPYLOAD]], ptr [[A_SROA_4_0_OUT_SROA_IDX2]], align 1, !dbg [[DBG95]] 275; CHECK-DEBUGLOC-NEXT: ret void, !dbg [[DBG96:![0-9]+]] 276; 277entry: 278 %a = alloca [16 x i8] 279 %raw2 = getelementptr inbounds [16 x i8], ptr %a, i32 0, i32 8 280 281 call void @llvm.memcpy.p0.p0.i32(ptr %a, ptr %out, i32 16, i1 false) 282 283 %val1 = load double, ptr %raw2, align 1 284 %val2 = load double, ptr %a, align 1 285 286 store double %val1, ptr %a, align 1 287 store double %val2, ptr %raw2, align 1 288 289 call void @llvm.memcpy.p0.p0.i32(ptr %out, ptr %a, i32 16, i1 false) 290 291 ret void 292} 293 294define void @test8() { 295; CHECK-LABEL: @test8( 296; CHECK-NEXT: [[PTR:%.*]] = alloca [5 x i32], align 1 297; CHECK-NEXT: call void @populate(ptr [[PTR]]) 298; CHECK-NEXT: [[VAL_FCA_0_GEP:%.*]] = getelementptr inbounds [5 x i32], ptr [[PTR]], i32 0, i32 0 299; CHECK-NEXT: [[VAL_FCA_0_LOAD:%.*]] = load i32, ptr [[VAL_FCA_0_GEP]], align 1 300; CHECK-NEXT: [[VAL_FCA_0_INSERT:%.*]] = insertvalue [5 x i32] poison, i32 [[VAL_FCA_0_LOAD]], 0 301; CHECK-NEXT: [[VAL_FCA_1_GEP:%.*]] = getelementptr inbounds [5 x i32], ptr [[PTR]], i32 0, i32 1 302; CHECK-NEXT: [[VAL_FCA_1_LOAD:%.*]] = load i32, ptr [[VAL_FCA_1_GEP]], align 1 303; CHECK-NEXT: [[VAL_FCA_1_INSERT:%.*]] = insertvalue [5 x i32] [[VAL_FCA_0_INSERT]], i32 [[VAL_FCA_1_LOAD]], 1 304; CHECK-NEXT: [[VAL_FCA_2_GEP:%.*]] = getelementptr inbounds [5 x i32], ptr [[PTR]], i32 0, i32 2 305; CHECK-NEXT: [[VAL_FCA_2_LOAD:%.*]] = load i32, ptr [[VAL_FCA_2_GEP]], align 1 306; CHECK-NEXT: [[VAL_FCA_2_INSERT:%.*]] = insertvalue [5 x i32] [[VAL_FCA_1_INSERT]], i32 [[VAL_FCA_2_LOAD]], 2 307; CHECK-NEXT: [[VAL_FCA_3_GEP:%.*]] = getelementptr inbounds [5 x i32], ptr [[PTR]], i32 0, i32 3 308; CHECK-NEXT: [[VAL_FCA_3_LOAD:%.*]] = load i32, ptr [[VAL_FCA_3_GEP]], align 1 309; CHECK-NEXT: [[VAL_FCA_3_INSERT:%.*]] = insertvalue [5 x i32] [[VAL_FCA_2_INSERT]], i32 [[VAL_FCA_3_LOAD]], 3 310; CHECK-NEXT: [[VAL_FCA_4_GEP:%.*]] = getelementptr inbounds [5 x i32], ptr [[PTR]], i32 0, i32 4 311; CHECK-NEXT: [[VAL_FCA_4_LOAD:%.*]] = load i32, ptr [[VAL_FCA_4_GEP]], align 1 312; CHECK-NEXT: [[VAL_FCA_4_INSERT:%.*]] = insertvalue [5 x i32] [[VAL_FCA_3_INSERT]], i32 [[VAL_FCA_4_LOAD]], 4 313; CHECK-NEXT: ret void 314; 315; CHECK-DEBUGLOC-LABEL: @test8( 316; CHECK-DEBUGLOC-NEXT: [[PTR:%.*]] = alloca [5 x i32], align 1, !dbg [[DBG102:![0-9]+]] 317; CHECK-DEBUGLOC-NEXT: #dbg_value(ptr [[PTR]], [[META99:![0-9]+]], !DIExpression(), [[DBG102]]) 318; CHECK-DEBUGLOC-NEXT: call void @populate(ptr [[PTR]]), !dbg [[DBG103:![0-9]+]] 319; CHECK-DEBUGLOC-NEXT: [[VAL_FCA_0_GEP:%.*]] = getelementptr inbounds [5 x i32], ptr [[PTR]], i32 0, i32 0, !dbg [[DBG104:![0-9]+]] 320; CHECK-DEBUGLOC-NEXT: [[VAL_FCA_0_LOAD:%.*]] = load i32, ptr [[VAL_FCA_0_GEP]], align 1, !dbg [[DBG104]] 321; CHECK-DEBUGLOC-NEXT: [[VAL_FCA_0_INSERT:%.*]] = insertvalue [5 x i32] poison, i32 [[VAL_FCA_0_LOAD]], 0, !dbg [[DBG104]] 322; CHECK-DEBUGLOC-NEXT: [[VAL_FCA_1_GEP:%.*]] = getelementptr inbounds [5 x i32], ptr [[PTR]], i32 0, i32 1, !dbg [[DBG104]] 323; CHECK-DEBUGLOC-NEXT: [[VAL_FCA_1_LOAD:%.*]] = load i32, ptr [[VAL_FCA_1_GEP]], align 1, !dbg [[DBG104]] 324; CHECK-DEBUGLOC-NEXT: [[VAL_FCA_1_INSERT:%.*]] = insertvalue [5 x i32] [[VAL_FCA_0_INSERT]], i32 [[VAL_FCA_1_LOAD]], 1, !dbg [[DBG104]] 325; CHECK-DEBUGLOC-NEXT: [[VAL_FCA_2_GEP:%.*]] = getelementptr inbounds [5 x i32], ptr [[PTR]], i32 0, i32 2, !dbg [[DBG104]] 326; CHECK-DEBUGLOC-NEXT: [[VAL_FCA_2_LOAD:%.*]] = load i32, ptr [[VAL_FCA_2_GEP]], align 1, !dbg [[DBG104]] 327; CHECK-DEBUGLOC-NEXT: [[VAL_FCA_2_INSERT:%.*]] = insertvalue [5 x i32] [[VAL_FCA_1_INSERT]], i32 [[VAL_FCA_2_LOAD]], 2, !dbg [[DBG104]] 328; CHECK-DEBUGLOC-NEXT: [[VAL_FCA_3_GEP:%.*]] = getelementptr inbounds [5 x i32], ptr [[PTR]], i32 0, i32 3, !dbg [[DBG104]] 329; CHECK-DEBUGLOC-NEXT: [[VAL_FCA_3_LOAD:%.*]] = load i32, ptr [[VAL_FCA_3_GEP]], align 1, !dbg [[DBG104]] 330; CHECK-DEBUGLOC-NEXT: [[VAL_FCA_3_INSERT:%.*]] = insertvalue [5 x i32] [[VAL_FCA_2_INSERT]], i32 [[VAL_FCA_3_LOAD]], 3, !dbg [[DBG104]] 331; CHECK-DEBUGLOC-NEXT: [[VAL_FCA_4_GEP:%.*]] = getelementptr inbounds [5 x i32], ptr [[PTR]], i32 0, i32 4, !dbg [[DBG104]] 332; CHECK-DEBUGLOC-NEXT: [[VAL_FCA_4_LOAD:%.*]] = load i32, ptr [[VAL_FCA_4_GEP]], align 1, !dbg [[DBG104]] 333; CHECK-DEBUGLOC-NEXT: [[VAL_FCA_4_INSERT:%.*]] = insertvalue [5 x i32] [[VAL_FCA_3_INSERT]], i32 [[VAL_FCA_4_LOAD]], 4, !dbg [[DBG104]] 334; CHECK-DEBUGLOC-NEXT: #dbg_value([5 x i32] [[VAL_FCA_4_INSERT]], [[META100:![0-9]+]], !DIExpression(), [[DBG104]]) 335; CHECK-DEBUGLOC-NEXT: ret void, !dbg [[DBG105:![0-9]+]] 336; 337 %ptr = alloca [5 x i32], align 1 338 call void @populate(ptr %ptr) 339 %val = load [5 x i32], ptr %ptr, align 1 340 ret void 341} 342 343define void @test9() { 344; CHECK-LABEL: @test9( 345; CHECK-NEXT: [[PTR:%.*]] = alloca [5 x i32], align 8 346; CHECK-NEXT: call void @populate(ptr [[PTR]]) 347; CHECK-NEXT: [[VAL_FCA_0_GEP:%.*]] = getelementptr inbounds [5 x i32], ptr [[PTR]], i32 0, i32 0 348; CHECK-NEXT: [[VAL_FCA_0_LOAD:%.*]] = load i32, ptr [[VAL_FCA_0_GEP]], align 8 349; CHECK-NEXT: [[VAL_FCA_0_INSERT:%.*]] = insertvalue [5 x i32] poison, i32 [[VAL_FCA_0_LOAD]], 0 350; CHECK-NEXT: [[VAL_FCA_1_GEP:%.*]] = getelementptr inbounds [5 x i32], ptr [[PTR]], i32 0, i32 1 351; CHECK-NEXT: [[VAL_FCA_1_LOAD:%.*]] = load i32, ptr [[VAL_FCA_1_GEP]], align 4 352; CHECK-NEXT: [[VAL_FCA_1_INSERT:%.*]] = insertvalue [5 x i32] [[VAL_FCA_0_INSERT]], i32 [[VAL_FCA_1_LOAD]], 1 353; CHECK-NEXT: [[VAL_FCA_2_GEP:%.*]] = getelementptr inbounds [5 x i32], ptr [[PTR]], i32 0, i32 2 354; CHECK-NEXT: [[VAL_FCA_2_LOAD:%.*]] = load i32, ptr [[VAL_FCA_2_GEP]], align 8 355; CHECK-NEXT: [[VAL_FCA_2_INSERT:%.*]] = insertvalue [5 x i32] [[VAL_FCA_1_INSERT]], i32 [[VAL_FCA_2_LOAD]], 2 356; CHECK-NEXT: [[VAL_FCA_3_GEP:%.*]] = getelementptr inbounds [5 x i32], ptr [[PTR]], i32 0, i32 3 357; CHECK-NEXT: [[VAL_FCA_3_LOAD:%.*]] = load i32, ptr [[VAL_FCA_3_GEP]], align 4 358; CHECK-NEXT: [[VAL_FCA_3_INSERT:%.*]] = insertvalue [5 x i32] [[VAL_FCA_2_INSERT]], i32 [[VAL_FCA_3_LOAD]], 3 359; CHECK-NEXT: [[VAL_FCA_4_GEP:%.*]] = getelementptr inbounds [5 x i32], ptr [[PTR]], i32 0, i32 4 360; CHECK-NEXT: [[VAL_FCA_4_LOAD:%.*]] = load i32, ptr [[VAL_FCA_4_GEP]], align 8 361; CHECK-NEXT: [[VAL_FCA_4_INSERT:%.*]] = insertvalue [5 x i32] [[VAL_FCA_3_INSERT]], i32 [[VAL_FCA_4_LOAD]], 4 362; CHECK-NEXT: ret void 363; 364; CHECK-DEBUGLOC-LABEL: @test9( 365; CHECK-DEBUGLOC-NEXT: [[PTR:%.*]] = alloca [5 x i32], align 8, !dbg [[DBG110:![0-9]+]] 366; CHECK-DEBUGLOC-NEXT: #dbg_value(ptr [[PTR]], [[META108:![0-9]+]], !DIExpression(), [[DBG110]]) 367; CHECK-DEBUGLOC-NEXT: call void @populate(ptr [[PTR]]), !dbg [[DBG111:![0-9]+]] 368; CHECK-DEBUGLOC-NEXT: [[VAL_FCA_0_GEP:%.*]] = getelementptr inbounds [5 x i32], ptr [[PTR]], i32 0, i32 0, !dbg [[DBG112:![0-9]+]] 369; CHECK-DEBUGLOC-NEXT: [[VAL_FCA_0_LOAD:%.*]] = load i32, ptr [[VAL_FCA_0_GEP]], align 8, !dbg [[DBG112]] 370; CHECK-DEBUGLOC-NEXT: [[VAL_FCA_0_INSERT:%.*]] = insertvalue [5 x i32] poison, i32 [[VAL_FCA_0_LOAD]], 0, !dbg [[DBG112]] 371; CHECK-DEBUGLOC-NEXT: [[VAL_FCA_1_GEP:%.*]] = getelementptr inbounds [5 x i32], ptr [[PTR]], i32 0, i32 1, !dbg [[DBG112]] 372; CHECK-DEBUGLOC-NEXT: [[VAL_FCA_1_LOAD:%.*]] = load i32, ptr [[VAL_FCA_1_GEP]], align 4, !dbg [[DBG112]] 373; CHECK-DEBUGLOC-NEXT: [[VAL_FCA_1_INSERT:%.*]] = insertvalue [5 x i32] [[VAL_FCA_0_INSERT]], i32 [[VAL_FCA_1_LOAD]], 1, !dbg [[DBG112]] 374; CHECK-DEBUGLOC-NEXT: [[VAL_FCA_2_GEP:%.*]] = getelementptr inbounds [5 x i32], ptr [[PTR]], i32 0, i32 2, !dbg [[DBG112]] 375; CHECK-DEBUGLOC-NEXT: [[VAL_FCA_2_LOAD:%.*]] = load i32, ptr [[VAL_FCA_2_GEP]], align 8, !dbg [[DBG112]] 376; CHECK-DEBUGLOC-NEXT: [[VAL_FCA_2_INSERT:%.*]] = insertvalue [5 x i32] [[VAL_FCA_1_INSERT]], i32 [[VAL_FCA_2_LOAD]], 2, !dbg [[DBG112]] 377; CHECK-DEBUGLOC-NEXT: [[VAL_FCA_3_GEP:%.*]] = getelementptr inbounds [5 x i32], ptr [[PTR]], i32 0, i32 3, !dbg [[DBG112]] 378; CHECK-DEBUGLOC-NEXT: [[VAL_FCA_3_LOAD:%.*]] = load i32, ptr [[VAL_FCA_3_GEP]], align 4, !dbg [[DBG112]] 379; CHECK-DEBUGLOC-NEXT: [[VAL_FCA_3_INSERT:%.*]] = insertvalue [5 x i32] [[VAL_FCA_2_INSERT]], i32 [[VAL_FCA_3_LOAD]], 3, !dbg [[DBG112]] 380; CHECK-DEBUGLOC-NEXT: [[VAL_FCA_4_GEP:%.*]] = getelementptr inbounds [5 x i32], ptr [[PTR]], i32 0, i32 4, !dbg [[DBG112]] 381; CHECK-DEBUGLOC-NEXT: [[VAL_FCA_4_LOAD:%.*]] = load i32, ptr [[VAL_FCA_4_GEP]], align 8, !dbg [[DBG112]] 382; CHECK-DEBUGLOC-NEXT: [[VAL_FCA_4_INSERT:%.*]] = insertvalue [5 x i32] [[VAL_FCA_3_INSERT]], i32 [[VAL_FCA_4_LOAD]], 4, !dbg [[DBG112]] 383; CHECK-DEBUGLOC-NEXT: #dbg_value([5 x i32] [[VAL_FCA_4_INSERT]], [[META109:![0-9]+]], !DIExpression(), [[DBG112]]) 384; CHECK-DEBUGLOC-NEXT: ret void, !dbg [[DBG113:![0-9]+]] 385; 386 %ptr = alloca [5 x i32], align 8 387 call void @populate(ptr %ptr) 388 %val = load [5 x i32], ptr %ptr, align 8 389 ret void 390} 391 392define void @test10() { 393; CHECK-LABEL: @test10( 394; CHECK-NEXT: [[PTR:%.*]] = alloca { i32, i8, i8, { i8, i16 } }, align 2 395; CHECK-NEXT: call void @populate(ptr [[PTR]]) 396; CHECK-NEXT: [[VAL_FCA_0_GEP:%.*]] = getelementptr inbounds { i32, i8, i8, { i8, i16 } }, ptr [[PTR]], i32 0, i32 0 397; CHECK-NEXT: [[VAL_FCA_0_LOAD:%.*]] = load i32, ptr [[VAL_FCA_0_GEP]], align 2 398; CHECK-NEXT: [[VAL_FCA_0_INSERT:%.*]] = insertvalue { i32, i8, i8, { i8, i16 } } poison, i32 [[VAL_FCA_0_LOAD]], 0 399; CHECK-NEXT: [[VAL_FCA_1_GEP:%.*]] = getelementptr inbounds { i32, i8, i8, { i8, i16 } }, ptr [[PTR]], i32 0, i32 1 400; CHECK-NEXT: [[VAL_FCA_1_LOAD:%.*]] = load i8, ptr [[VAL_FCA_1_GEP]], align 2 401; CHECK-NEXT: [[VAL_FCA_1_INSERT:%.*]] = insertvalue { i32, i8, i8, { i8, i16 } } [[VAL_FCA_0_INSERT]], i8 [[VAL_FCA_1_LOAD]], 1 402; CHECK-NEXT: [[VAL_FCA_2_GEP:%.*]] = getelementptr inbounds { i32, i8, i8, { i8, i16 } }, ptr [[PTR]], i32 0, i32 2 403; CHECK-NEXT: [[VAL_FCA_2_LOAD:%.*]] = load i8, ptr [[VAL_FCA_2_GEP]], align 1 404; CHECK-NEXT: [[VAL_FCA_2_INSERT:%.*]] = insertvalue { i32, i8, i8, { i8, i16 } } [[VAL_FCA_1_INSERT]], i8 [[VAL_FCA_2_LOAD]], 2 405; CHECK-NEXT: [[VAL_FCA_3_0_GEP:%.*]] = getelementptr inbounds { i32, i8, i8, { i8, i16 } }, ptr [[PTR]], i32 0, i32 3, i32 0 406; CHECK-NEXT: [[VAL_FCA_3_0_LOAD:%.*]] = load i8, ptr [[VAL_FCA_3_0_GEP]], align 2 407; CHECK-NEXT: [[VAL_FCA_3_0_INSERT:%.*]] = insertvalue { i32, i8, i8, { i8, i16 } } [[VAL_FCA_2_INSERT]], i8 [[VAL_FCA_3_0_LOAD]], 3, 0 408; CHECK-NEXT: [[VAL_FCA_3_1_GEP:%.*]] = getelementptr inbounds { i32, i8, i8, { i8, i16 } }, ptr [[PTR]], i32 0, i32 3, i32 1 409; CHECK-NEXT: [[VAL_FCA_3_1_LOAD:%.*]] = load i16, ptr [[VAL_FCA_3_1_GEP]], align 2 410; CHECK-NEXT: [[VAL_FCA_3_1_INSERT:%.*]] = insertvalue { i32, i8, i8, { i8, i16 } } [[VAL_FCA_3_0_INSERT]], i16 [[VAL_FCA_3_1_LOAD]], 3, 1 411; CHECK-NEXT: ret void 412; 413; CHECK-DEBUGLOC-LABEL: @test10( 414; CHECK-DEBUGLOC-NEXT: [[PTR:%.*]] = alloca { i32, i8, i8, { i8, i16 } }, align 2, !dbg [[DBG119:![0-9]+]] 415; CHECK-DEBUGLOC-NEXT: #dbg_value(ptr [[PTR]], [[META116:![0-9]+]], !DIExpression(), [[DBG119]]) 416; CHECK-DEBUGLOC-NEXT: call void @populate(ptr [[PTR]]), !dbg [[DBG120:![0-9]+]] 417; CHECK-DEBUGLOC-NEXT: [[VAL_FCA_0_GEP:%.*]] = getelementptr inbounds { i32, i8, i8, { i8, i16 } }, ptr [[PTR]], i32 0, i32 0, !dbg [[DBG121:![0-9]+]] 418; CHECK-DEBUGLOC-NEXT: [[VAL_FCA_0_LOAD:%.*]] = load i32, ptr [[VAL_FCA_0_GEP]], align 2, !dbg [[DBG121]] 419; CHECK-DEBUGLOC-NEXT: [[VAL_FCA_0_INSERT:%.*]] = insertvalue { i32, i8, i8, { i8, i16 } } poison, i32 [[VAL_FCA_0_LOAD]], 0, !dbg [[DBG121]] 420; CHECK-DEBUGLOC-NEXT: [[VAL_FCA_1_GEP:%.*]] = getelementptr inbounds { i32, i8, i8, { i8, i16 } }, ptr [[PTR]], i32 0, i32 1, !dbg [[DBG121]] 421; CHECK-DEBUGLOC-NEXT: [[VAL_FCA_1_LOAD:%.*]] = load i8, ptr [[VAL_FCA_1_GEP]], align 2, !dbg [[DBG121]] 422; CHECK-DEBUGLOC-NEXT: [[VAL_FCA_1_INSERT:%.*]] = insertvalue { i32, i8, i8, { i8, i16 } } [[VAL_FCA_0_INSERT]], i8 [[VAL_FCA_1_LOAD]], 1, !dbg [[DBG121]] 423; CHECK-DEBUGLOC-NEXT: [[VAL_FCA_2_GEP:%.*]] = getelementptr inbounds { i32, i8, i8, { i8, i16 } }, ptr [[PTR]], i32 0, i32 2, !dbg [[DBG121]] 424; CHECK-DEBUGLOC-NEXT: [[VAL_FCA_2_LOAD:%.*]] = load i8, ptr [[VAL_FCA_2_GEP]], align 1, !dbg [[DBG121]] 425; CHECK-DEBUGLOC-NEXT: [[VAL_FCA_2_INSERT:%.*]] = insertvalue { i32, i8, i8, { i8, i16 } } [[VAL_FCA_1_INSERT]], i8 [[VAL_FCA_2_LOAD]], 2, !dbg [[DBG121]] 426; CHECK-DEBUGLOC-NEXT: [[VAL_FCA_3_0_GEP:%.*]] = getelementptr inbounds { i32, i8, i8, { i8, i16 } }, ptr [[PTR]], i32 0, i32 3, i32 0, !dbg [[DBG121]] 427; CHECK-DEBUGLOC-NEXT: [[VAL_FCA_3_0_LOAD:%.*]] = load i8, ptr [[VAL_FCA_3_0_GEP]], align 2, !dbg [[DBG121]] 428; CHECK-DEBUGLOC-NEXT: [[VAL_FCA_3_0_INSERT:%.*]] = insertvalue { i32, i8, i8, { i8, i16 } } [[VAL_FCA_2_INSERT]], i8 [[VAL_FCA_3_0_LOAD]], 3, 0, !dbg [[DBG121]] 429; CHECK-DEBUGLOC-NEXT: [[VAL_FCA_3_1_GEP:%.*]] = getelementptr inbounds { i32, i8, i8, { i8, i16 } }, ptr [[PTR]], i32 0, i32 3, i32 1, !dbg [[DBG121]] 430; CHECK-DEBUGLOC-NEXT: [[VAL_FCA_3_1_LOAD:%.*]] = load i16, ptr [[VAL_FCA_3_1_GEP]], align 2, !dbg [[DBG121]] 431; CHECK-DEBUGLOC-NEXT: [[VAL_FCA_3_1_INSERT:%.*]] = insertvalue { i32, i8, i8, { i8, i16 } } [[VAL_FCA_3_0_INSERT]], i16 [[VAL_FCA_3_1_LOAD]], 3, 1, !dbg [[DBG121]] 432; CHECK-DEBUGLOC-NEXT: #dbg_value({ i32, i8, i8, { i8, i16 } } [[VAL_FCA_3_1_INSERT]], [[META117:![0-9]+]], !DIExpression(), [[DBG121]]) 433; CHECK-DEBUGLOC-NEXT: ret void, !dbg [[DBG122:![0-9]+]] 434; 435 %ptr = alloca {i32, i8, i8, {i8, i16}}, align 2 436 call void @populate(ptr %ptr) 437 %val = load {i32, i8, i8, {i8, i16}}, ptr %ptr, align 2 438 ret void 439} 440 441%struct = type { i32, i32 } 442define dso_local i32 @pr45010(ptr %A) { 443; CHECK-LABEL: @pr45010( 444; CHECK-NEXT: [[B_SROA_0:%.*]] = alloca i32, align 4 445; CHECK-NEXT: [[TMP1:%.*]] = load i32, ptr [[A:%.*]], align 4 446; CHECK-NEXT: store atomic volatile i32 [[TMP1]], ptr [[B_SROA_0]] release, align 4 447; CHECK-NEXT: [[B_SROA_0_0_B_SROA_0_0_X:%.*]] = load atomic volatile i32, ptr [[B_SROA_0]] acquire, align 4 448; CHECK-NEXT: ret i32 [[B_SROA_0_0_B_SROA_0_0_X]] 449; 450; CHECK-DEBUGLOC-LABEL: @pr45010( 451; CHECK-DEBUGLOC-NEXT: [[B_SROA_0:%.*]] = alloca i32, align 4, !dbg [[DBG129:![0-9]+]] 452; CHECK-DEBUGLOC-NEXT: #dbg_value(ptr [[B_SROA_0]], [[META125:![0-9]+]], !DIExpression(DW_OP_LLVM_fragment, 0, 32), [[DBG129]]) 453; CHECK-DEBUGLOC-NEXT: #dbg_value(ptr undef, [[META125]], !DIExpression(), [[DBG129]]) 454; CHECK-DEBUGLOC-NEXT: [[TMP1:%.*]] = load i32, ptr [[A:%.*]], align 4, !dbg [[DBG130:![0-9]+]] 455; CHECK-DEBUGLOC-NEXT: #dbg_value(i32 [[TMP1]], [[META126:![0-9]+]], !DIExpression(), [[DBG130]]) 456; CHECK-DEBUGLOC-NEXT: store atomic volatile i32 [[TMP1]], ptr [[B_SROA_0]] release, align 4, !dbg [[DBG131:![0-9]+]] 457; CHECK-DEBUGLOC-NEXT: [[B_SROA_0_0_B_SROA_0_0_X:%.*]] = load atomic volatile i32, ptr [[B_SROA_0]] acquire, align 4, !dbg [[DBG132:![0-9]+]] 458; CHECK-DEBUGLOC-NEXT: #dbg_value(i32 [[B_SROA_0_0_B_SROA_0_0_X]], [[META128:![0-9]+]], !DIExpression(), [[DBG132]]) 459; CHECK-DEBUGLOC-NEXT: ret i32 [[B_SROA_0_0_B_SROA_0_0_X]], !dbg [[DBG133:![0-9]+]] 460; 461 %B = alloca %struct, align 4 462 %1 = load i32, ptr %A, align 4 463 store atomic volatile i32 %1, ptr %B release, align 4 464 %x = load atomic volatile i32, ptr %B acquire, align 4 465 ret i32 %x 466} 467 468declare void @populate(ptr) 469;; NOTE: These prefixes are unused and the list is autogenerated. Do not add tests below this line: 470; CHECK-MODIFY-CFG: {{.*}} 471; CHECK-PRESERVE-CFG: {{.*}} 472