brintos

brintos / llvm-project-archived public Read only

0
0
Text · 90.3 KiB · 15803f7 Raw
2073 lines · plain
1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py2; RUN: opt < %s -passes='sroa<preserve-cfg>' -S | FileCheck %s --check-prefixes=CHECK,CHECK-PRESERVE-CFG3; RUN: opt < %s -passes='sroa<modify-cfg>' -S | FileCheck %s --check-prefixes=CHECK,CHECK-MODIFY-CFG4 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(ptr nocapture)8declare void @llvm.lifetime.end.p0(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 i3214; CHECK-NEXT:    [[SUM1:%.*]] = add i32 0, [[V2_INT]]15; CHECK-NEXT:    ret i32 [[SUM1]]16;17entry:18  %a1 = alloca i3219  %a2 = alloca float20 21  call void @llvm.lifetime.start.p0(ptr %a1)22 23  store i32 0, ptr %a124  %v1 = load i32, ptr %a125 26  call void @llvm.lifetime.end.p0(ptr %a1)27 28  call void @llvm.lifetime.start.p0(ptr %a2)29 30  store float 0.0, ptr %a231  %v2 = load float , ptr %a232  %v2.int = bitcast float %v2 to i3233  %sum1 = add i32 %v1, %v2.int34 35  call void @llvm.lifetime.end.p0(ptr %a2)36 37  ret i32 %sum138}39 40define i32 @test1() {41; CHECK-LABEL: @test1(42; CHECK-NEXT:  entry:43; CHECK-NEXT:    ret i32 044;45entry:46  %X = alloca { i32, float }47  %Y = getelementptr { i32, float }, ptr %X, i64 0, i32 048  store i32 0, ptr %Y49  %Z = load i32, ptr %Y50  ret i32 %Z51}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 %A63  br label %L264 65L2:66  %Z = load i64, ptr %A67  ret i64 %Z68}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) %B81  br label %L282 83L2:84  %Z = load i64, ptr addrspace(1) %B85  ret i64 %Z86}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 3299  %gepB = getelementptr i64, ptr addrspace(1) %B, i16 4100  store i64 %X, ptr addrspace(1) %gepB, align 1101  br label %L2102 103L2:104  %Z = load i64, ptr %gepA, align 1105  ret i64 %Z106}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 1113; CHECK-NEXT:    [[A_SROA_0_2_GEPB_SROA_IDX:%.*]] = getelementptr inbounds i8, ptr [[A_SROA_0]], i16 2114; 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 1116; 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 1119; 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 30125  %gepB = getelementptr i64, ptr addrspace(1) %B, i16 4126  store i64 %X, ptr addrspace(1) %gepB, align 1127  br label %L2128 129L2:130  %Z = load i64, ptr %gepA, align 1131  ret i64 %Z132}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 1138; CHECK-NEXT:    [[A_SROA_3:%.*]] = alloca [99 x i8], align 1139; CHECK-NEXT:    [[A_SROA_32:%.*]] = alloca [16 x i8], align 1140; CHECK-NEXT:    [[A_SROA_15:%.*]] = alloca [42 x i8], align 1141; CHECK-NEXT:    [[A_SROA_16:%.*]] = alloca [7 x i8], align 1142; CHECK-NEXT:    [[A_SROA_235:%.*]] = alloca [7 x i8], align 1143; CHECK-NEXT:    [[A_SROA_31:%.*]] = alloca [85 x i8], align 1144; 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 42146; 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 43148; 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 142150; 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 158152; 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 200154; 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 207156; 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 208158; 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 215160; 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 1166; 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 2168; 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 3170; 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 4172; 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 5174; 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 6176; 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 7178; 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 8180; 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 1185; 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 2187; 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 3189; 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 1192; 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 1194; 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 1196; 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 2198; 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 3200; 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 39202; 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 3204; 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 2206; 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 1209; 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 2211; 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 5213; 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 42216; 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 43218; 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 142220; 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 158222; 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 200224; 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 207226; 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 208228; 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 215230; 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 void232;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 !0237 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 42240  store i8 0, ptr %c241 242  ; Make a sequence of overlapping stores to the array. These overlap both in243  ; forward strides and in shrinking accesses.244  %overlap.1.i8 = getelementptr [300 x i8], ptr %a, i64 0, i64 142245  %overlap.2.i8 = getelementptr [300 x i8], ptr %a, i64 0, i64 143246  %overlap.3.i8 = getelementptr [300 x i8], ptr %a, i64 0, i64 144247  %overlap.4.i8 = getelementptr [300 x i8], ptr %a, i64 0, i64 145248  %overlap.5.i8 = getelementptr [300 x i8], ptr %a, i64 0, i64 146249  %overlap.6.i8 = getelementptr [300 x i8], ptr %a, i64 0, i64 147250  %overlap.7.i8 = getelementptr [300 x i8], ptr %a, i64 0, i64 148251  %overlap.8.i8 = getelementptr [300 x i8], ptr %a, i64 0, i64 149252  %overlap.9.i8 = getelementptr [300 x i8], ptr %a, i64 0, i64 150253  store i8 1, ptr %overlap.1.i8, !tbaa !3254  store i16 1, ptr %overlap.1.i8, !tbaa !5255  store i32 1, ptr %overlap.1.i8, !tbaa !7256  store i64 1, ptr %overlap.1.i8, !tbaa !9257  store i64 2, ptr %overlap.2.i8, !tbaa !11258  store i64 3, ptr %overlap.3.i8, !tbaa !13259  store i64 4, ptr %overlap.4.i8, !tbaa !15260  store i64 5, ptr %overlap.5.i8, !tbaa !17261  store i64 6, ptr %overlap.6.i8, !tbaa !19262  store i64 7, ptr %overlap.7.i8, !tbaa !21263  store i64 8, ptr %overlap.8.i8, !tbaa !23264  store i64 9, ptr %overlap.9.i8, !tbaa !25265 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 200268  %overlap2.1.1.i8 = getelementptr [300 x i8], ptr %a, i64 0, i64 201269  %overlap2.1.2.i8 = getelementptr [300 x i8], ptr %a, i64 0, i64 202270  %overlap2.1.3.i8 = getelementptr [300 x i8], ptr %a, i64 0, i64 203271 272  %overlap2.2.0.i8 = getelementptr [300 x i8], ptr %a, i64 0, i64 208273  %overlap2.2.1.i8 = getelementptr [300 x i8], ptr %a, i64 0, i64 209274  %overlap2.2.2.i8 = getelementptr [300 x i8], ptr %a, i64 0, i64 210275  %overlap2.2.3.i8 = getelementptr [300 x i8], ptr %a, i64 0, i64 211276 277  store i8 1,  ptr  %overlap2.1.0.i8, !tbaa !27278  store i16 1, ptr %overlap2.1.0.i8, !tbaa !29279  store i32 1, ptr %overlap2.1.0.i8, !tbaa !31280  store i32 2, ptr %overlap2.1.1.i8, !tbaa !33281  store i32 3, ptr %overlap2.1.2.i8, !tbaa !35282  store i32 4, ptr %overlap2.1.3.i8, !tbaa !37283 284  store i32 1, ptr %overlap2.2.0.i8, !tbaa !39285  store i8 1,  ptr  %overlap2.2.1.i8, !tbaa !41286  store i16 1, ptr %overlap2.2.1.i8, !tbaa !43287  store i32 1, ptr %overlap2.2.1.i8, !tbaa !45288  store i32 3, ptr %overlap2.2.2.i8, !tbaa !47289  store i32 4, ptr %overlap2.2.3.i8, !tbaa !49290 291  %overlap2.prefix = getelementptr i8, ptr %overlap2.1.1.i8, i64 -4292  call void @llvm.memcpy.p0.p0.i32(ptr %overlap2.prefix, ptr %src, i32 8, i1 false), !tbaa !51293 294  ; Bridge between the overlapping areas295  call void @llvm.memset.p0.i32(ptr %overlap2.1.2.i8, i8 42, i32 8, i1 false), !tbaa !53296; ...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 !55300 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 !57303 304  call void @llvm.memcpy.p0.p0.i32(ptr %dst, ptr %a, i32 300, i1 false), !tbaa !59305 306  ret void307}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 1313; CHECK-NEXT:    [[A_SROA_2_SROA_4:%.*]] = alloca [7 x i8], align 1314; CHECK-NEXT:    [[A_SROA_3:%.*]] = alloca [10 x i8], align 1315; CHECK-NEXT:    [[A_SROA_31_SROA_5:%.*]] = alloca [7 x i8], align 1316; CHECK-NEXT:    [[A_SROA_6_SROA_4:%.*]] = alloca [7 x i8], align 1317; CHECK-NEXT:    [[A_SROA_7:%.*]] = alloca [40 x i8], align 1318; 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 20320; 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 2322; 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 3324; 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 30326; 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 40328; 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 2330; 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 3332; 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 50334; 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 2336; 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 3338; 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 60340; 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 20345; 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 2347; 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 3349; 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 30351; 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 40353; 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 2355; 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 3357; 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 50359; 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 2361; 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 3363; 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 60365; 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 void367;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 !0372 373  %a.src.1 = getelementptr [100 x i8], ptr %a, i64 0, i64 20374  %a.dst.1 = getelementptr [100 x i8], ptr %a, i64 0, i64 40375  call void @llvm.memcpy.p0.p0.i32(ptr %a.dst.1, ptr %a.src.1, i32 10, i1 false), !tbaa !3376 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 42379  store i8 0, ptr %c380 381  %a.src.2 = getelementptr [100 x i8], ptr %a, i64 0, i64 50382  call void @llvm.memmove.p0.p0.i32(ptr %a.dst.1, ptr %a.src.2, i32 10, i1 false), !tbaa !5383 384  call void @llvm.memcpy.p0.p0.i32(ptr %dst, ptr %a, i32 100, i1 false), !tbaa !7385 386  ret void387}388 389declare void @llvm.memcpy.p0.p0.i32(ptr nocapture, ptr nocapture, i32, i1) nounwind390declare void @llvm.memcpy.p1.p0.i32(ptr addrspace(1) nocapture, ptr nocapture, i32, i1) nounwind391declare void @llvm.memmove.p0.p0.i32(ptr nocapture, ptr nocapture, i32, i1) nounwind392declare void @llvm.memset.p0.i32(ptr nocapture, i8, i32, i1) nounwind393 394define i16 @test5() {395; CHECK-LABEL: @test5(396; CHECK-NEXT:  entry:397; CHECK-NEXT:    [[TMP0:%.*]] = bitcast float 0.000000e+00 to i32398; CHECK-NEXT:    [[A_SROA_0_2_EXTRACT_SHIFT:%.*]] = lshr i32 [[TMP0]], 16399; CHECK-NEXT:    [[A_SROA_0_2_EXTRACT_TRUNC:%.*]] = trunc i32 [[A_SROA_0_2_EXTRACT_SHIFT]] to i16400; CHECK-NEXT:    ret i16 [[A_SROA_0_2_EXTRACT_TRUNC]]401;402entry:403  %a = alloca [4 x i8]404  store float 0.0, ptr %a405  %ptr = getelementptr [4 x i8], ptr %a, i32 0, i32 2406  %val = load i16, ptr %ptr407  ret i16 %val408}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 i32414; CHECK-NEXT:    [[A_SROA_0_2_EXTRACT_SHIFT:%.*]] = lshr i32 [[TMP0]], 16415; CHECK-NEXT:    [[A_SROA_0_2_EXTRACT_TRUNC:%.*]] = trunc i32 [[A_SROA_0_2_EXTRACT_SHIFT]] to i16416; 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.as1422  %ptr = getelementptr [4 x i8], ptr %a, i32 0, i32 2423  %val = load i16, ptr %ptr424  ret i16 %val425}426 427define i32 @test6() {428; CHECK-LABEL: @test6(429; CHECK-NEXT:  entry:430; CHECK-NEXT:    [[A_SROA_0:%.*]] = alloca i32, align 4431; CHECK-NEXT:    store volatile i32 707406378, ptr [[A_SROA_0]], align 4432; CHECK-NEXT:    [[A_SROA_0_0_A_SROA_0_0_VAL:%.*]] = load i32, ptr [[A_SROA_0]], align 4433; 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 %a439  ret i32 %val440}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 4446; 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 void451;452entry:453  %a = alloca [4 x i8]454  call void @llvm.memcpy.p0.p0.i32(ptr %a, ptr %src, i32 4, i1 true), !tbaa !0455  call void @llvm.memcpy.p0.p0.i32(ptr %dst, ptr %a, i32 4, i1 true), !tbaa !3456  ret void457}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 1467; 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 1470; 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]], 0472; CHECK-NEXT:    [[RESULT2:%.*]] = insertvalue [[S2]] [[RESULT1]], ptr [[S2_NEXT_NEXT]], 1473; CHECK-NEXT:    ret [[S2]] [[RESULT2]]474;475entry:476  %new = alloca %S2477 478  %s2.next.ptr = getelementptr %S2, ptr %arg, i64 0, i32 1479  %s2.next = load ptr, ptr %s2.next.ptr, !tbaa !0480 481  %s2.next.s1 = load ptr, ptr %s2.next, !tbaa !3482  store ptr %s2.next.s1, ptr %new, !tbaa !5483  %s2.next.next.ptr = getelementptr %S2, ptr %s2.next, i64 0, i32 1484  %s2.next.next = load ptr, ptr %s2.next.next.ptr, !tbaa !7485  %new.next.ptr = getelementptr %S2, ptr %new, i64 0, i32 1486  store ptr %s2.next.next, ptr %new.next.ptr, !tbaa !9487 488  %new.s1 = load ptr, ptr %new489  %result1 = insertvalue %S2 poison, ptr %new.s1, 0490  %new.next = load ptr, ptr %new.next.ptr491  %result2 = insertvalue %S2 %result1, ptr %new.next, 1492  ret %S2 %result2493}494 495define i64 @test9() {496; Ensure we can handle loads off the end of an alloca even when wrapped in497; weird bit casts and types. This is valid IR due to the alignment and masking498; 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 i64504; CHECK-NEXT:    [[A_SROA_3_0_INSERT_SHIFT:%.*]] = shl i64 [[A_SROA_3_0_INSERT_EXT]], 16505; CHECK-NEXT:    [[A_SROA_3_0_INSERT_MASK:%.*]] = and i64 undef, -16711681506; 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 i64508; CHECK-NEXT:    [[A_SROA_2_0_INSERT_SHIFT:%.*]] = shl i64 [[A_SROA_2_0_INSERT_EXT]], 8509; CHECK-NEXT:    [[A_SROA_2_0_INSERT_MASK:%.*]] = and i64 [[A_SROA_3_0_INSERT_INSERT]], -65281510; 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 i64512; CHECK-NEXT:    [[A_SROA_0_0_INSERT_MASK:%.*]] = and i64 [[A_SROA_2_0_INSERT_INSERT]], -256513; 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]], 16777215515; CHECK-NEXT:    ret i64 [[RESULT]]516;517entry:518  %a = alloca { [3 x i8] }, align 8519  store i8 0, ptr %a, align 1520  %gep2 = getelementptr inbounds { [3 x i8] }, ptr %a, i32 0, i32 0, i32 1521  store i8 0, ptr %gep2, align 1522  %gep3 = getelementptr inbounds { [3 x i8] }, ptr %a, i32 0, i32 0, i32 2523  store i8 26, ptr %gep3, align 1524  %load = load i64, ptr %a525  %result = and i64 %load, 16777215526  ret i64 %result527}528 529define ptr @test10() {530; CHECK-LABEL: @test10(531; CHECK-NEXT:  entry:532; CHECK-NEXT:    [[TMP0:%.*]] = ptrtoint ptr null to i64533; CHECK-NEXT:    ret ptr null534;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 %a539  ret ptr %s2ptr540}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 0548; CHECK:       bad:549; CHECK-NEXT:    ret i32 poison550;551entry:552  %X = alloca i32553  br i1 %c1, label %good, label %bad554 555good:556  store i32 0, ptr %X557  %Z = load i32, ptr %X558  ret i32 %Z559 560bad:561  %Y2 = getelementptr i32, ptr %X, i64 1562  store i32 0, ptr %Y2563  %Z2 = load i32, ptr %Y2564  ret i32 %Z2565}566 567define i8 @test12() {568; We fully promote these to the i24 load or store size, resulting in just masks569; 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 i24575; CHECK-NEXT:    [[A_SROA_3_0_INSERT_SHIFT:%.*]] = shl i24 [[A_SROA_3_0_INSERT_EXT]], 16576; CHECK-NEXT:    [[A_SROA_3_0_INSERT_MASK:%.*]] = and i24 undef, 65535577; 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 i24579; CHECK-NEXT:    [[A_SROA_2_0_INSERT_SHIFT:%.*]] = shl i24 [[A_SROA_2_0_INSERT_EXT]], 8580; CHECK-NEXT:    [[A_SROA_2_0_INSERT_MASK:%.*]] = and i24 [[A_SROA_3_0_INSERT_INSERT]], -65281581; 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 i24583; CHECK-NEXT:    [[A_SROA_0_0_INSERT_MASK:%.*]] = and i24 [[A_SROA_2_0_INSERT_INSERT]], -256584; 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 i8586; CHECK-NEXT:    [[B_SROA_2_0_EXTRACT_SHIFT:%.*]] = lshr i24 [[A_SROA_0_0_INSERT_INSERT]], 8587; CHECK-NEXT:    [[B_SROA_2_0_EXTRACT_TRUNC:%.*]] = trunc i24 [[B_SROA_2_0_EXTRACT_SHIFT]] to i8588; CHECK-NEXT:    [[B_SROA_3_0_EXTRACT_SHIFT:%.*]] = lshr i24 [[A_SROA_0_0_INSERT_INSERT]], 16589; CHECK-NEXT:    [[B_SROA_3_0_EXTRACT_TRUNC:%.*]] = trunc i24 [[B_SROA_3_0_EXTRACT_SHIFT]] to i8590; 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 %a599  %a1ptr = getelementptr [3 x i8], ptr %a, i64 0, i32 1600  store i8 0, ptr %a1ptr601  %a2ptr = getelementptr [3 x i8], ptr %a, i64 0, i32 2602  store i8 0, ptr %a2ptr603  %ai = load i24, ptr %a604 605  store i24 %ai, ptr %b606  %b0 = load i8, ptr %b607  %b1ptr = getelementptr [3 x i8], ptr %b, i64 0, i32 1608  %b1 = load i8, ptr %b1ptr609  %b2ptr = getelementptr [3 x i8], ptr %b, i64 0, i32 2610  %b2 = load i8, ptr %b2ptr611 612  %bsum0 = add i8 %b0, %b1613  %bsum1 = add i8 %bsum0, %b2614  ret i8 %bsum1615}616 617define i32 @test13() {618; Ensure we don't crash and handle undefined loads that straddle the end of the619; allocation.620;621; CHECK-LABEL: @test13(622; CHECK-NEXT:  entry:623; CHECK-NEXT:    [[A_SROA_2_2_LOAD_EXT:%.*]] = zext i8 0 to i16624; CHECK-NEXT:    [[RET:%.*]] = zext i16 [[A_SROA_2_2_LOAD_EXT]] to i32625; CHECK-NEXT:    ret i32 [[RET]]626;627entry:628  %a = alloca [3 x i8], align 2629  store i8 0, ptr %a630  %b1ptr = getelementptr [3 x i8], ptr %a, i64 0, i32 1631  store i8 0, ptr %b1ptr632  %b2ptr = getelementptr [3 x i8], ptr %a, i64 0, i32 2633  store i8 0, ptr %b2ptr634  %iptrgep = getelementptr i16, ptr %a, i64 1635  %i = load i16, ptr %iptrgep636  %ret = zext i16 %i to i32637  ret i32 %ret638}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, but644; also gain enough data to prove they must be dead allocas due to GEPs that walk645; across two adjacent allocas. Test that we don't try to promote or otherwise646; 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 void651;652entry:653  %a = alloca %test14.struct654  %p = alloca ptr655  %0 = getelementptr i8, ptr %a, i64 12656  %1 = load i32, ptr %a, align 4657  store i32 %1, ptr %0, align 4658  %2 = getelementptr inbounds i32, ptr %0, i32 1659  %3 = getelementptr inbounds i32, ptr %a, i32 1660  %4 = load i32, ptr %3, align 4661  store i32 %4, ptr %2, align 4662  %5 = getelementptr inbounds i32, ptr %0, i32 2663  %6 = getelementptr inbounds i32, ptr %a, i32 2664  %7 = load i32, ptr %6, align 4665  store i32 %7, ptr %5, align 4666  ret void667}668 669define i32 @test15(i1 %flag) nounwind uwtable {670; Ensure that when there are dead instructions using an alloca that are not671; 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 i64682  %l1 = alloca i64683  %l2 = alloca i64684  %l3 = alloca i64685  br label %loop686 687loop:688  %dead3 = phi ptr [ %gep3, %loop ], [ null, %entry ]689 690  store i64 1879048192, ptr %l0, align 8691  %gep0 = getelementptr i8, ptr %l0, i64 3692 693  store i64 1879048192, ptr %l1, align 8694  %gep1 = getelementptr i8, ptr %l1, i64 3695  %dead1 = getelementptr i8, ptr %gep1, i64 1696 697  store i64 1879048192, ptr %l2, align 8698  %gep2.1 = getelementptr i8, ptr %l2, i64 1699  %gep2.2 = getelementptr i8, ptr %l2, i64 3700  ; Note that this select should get visited multiple times due to using two701  ; different GEPs off the same alloca. We should only delete it once.702  %dead2 = select i1 %flag, ptr %gep2.1, ptr %gep2.2703 704  store i64 1879048192, ptr %l3, align 8705  %gep3 = getelementptr i8, ptr %l3, i64 3706 707  br label %loop708}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 void718;719entry:720  %a = alloca [3 x i8]721  call void @llvm.memcpy.p0.p0.i32(ptr %a, ptr %src, i32 4, i1 false), !tbaa !0722  store i24 0, ptr %a, !tbaa !3723  call void @llvm.memcpy.p0.p0.i32(ptr %dst, ptr %a, i32 4, i1 false), !tbaa !5724  ret void725}726 727define void @test17(ptr %src, ptr %dst) {728; Ensure that we can rewrite unpromotable memcpys which extend past the end of729; the alloca.730;731; CHECK-LABEL: @test17(732; CHECK-NEXT:  entry:733; CHECK-NEXT:    [[A:%.*]] = alloca [3 x i8], align 1734; 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 void737;738entry:739  %a = alloca [3 x i8]740  call void @llvm.memcpy.p0.p0.i32(ptr %a, ptr %src, i32 4, i1 true), !tbaa !0741  call void @llvm.memcpy.p0.p0.i32(ptr %dst, ptr %a, i32 4, i1 true), !tbaa !3742  ret void743}744 745define void @test18(ptr %src, ptr %dst, i32 %size) {746; Preserve transfer intrinsics with a variable size, even if they overlap with747; fixed size operations. Further, continue to split and promote allocas preceding748; the variable sized intrinsic.749;750; CHECK-LABEL: @test18(751; CHECK-NEXT:  entry:752; CHECK-NEXT:    [[A_SROA_33:%.*]] = alloca [34 x i8], align 1753; 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 4755; 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 4760; 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 void763;764entry:765  %a = alloca [42 x i8]766  call void @llvm.memcpy.p0.p0.i32(ptr %a, ptr %src, i32 8, i1 false), !tbaa !0767  %ptr2 = getelementptr [42 x i8], ptr %a, i32 0, i32 8768  call void @llvm.memcpy.p0.p0.i32(ptr %ptr2, ptr %src, i32 %size, i1 false), !tbaa !3769  call void @llvm.memset.p0.i32(ptr %ptr2, i8 42, i32 %size, i1 false), !tbaa !5770  store i32 42, ptr %a, !tbaa !7771  call void @llvm.memcpy.p0.p0.i32(ptr %dst, ptr %a, i32 8, i1 false), !tbaa !9772  call void @llvm.memcpy.p0.p0.i32(ptr %dst, ptr %ptr2, i32 %size, i1 false), !tbaa !11773  ret void774}775 776%opaque = type opaque777 778define i64 @test19(ptr %x) {779; This input will cause us to try to compute a natural GEP when rewriting780; 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 behaves782; reasonably now.783;784; CHECK-LABEL: @test19(785; CHECK-NEXT:  entry:786; CHECK-NEXT:    [[A_SROA_0_0_COPYLOAD:%.*]] = load i64, ptr [[X:%.*]], align 1787; CHECK-NEXT:    [[A_SROA_2_0_X_SROA_IDX:%.*]] = getelementptr inbounds i8, ptr [[X]], i64 8788; CHECK-NEXT:    [[A_SROA_2_0_COPYLOAD:%.*]] = load ptr, ptr [[A_SROA_2_0_X_SROA_IDX]], align 1789; 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 0795  %val = load i64, ptr %gep796  ret i64 %val797}798 799declare void @llvm.memcpy.p0.p1.i32(ptr nocapture, ptr addrspace(1) nocapture, i32, i32, i1) nounwind800 801define i64 @test19_addrspacecast(ptr %x) {802; This input will cause us to try to compute a natural GEP when rewriting803; 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 behaves805; 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 1811; CHECK-NEXT:    [[A_SROA_2_0_CAST1_SROA_IDX:%.*]] = getelementptr inbounds i8, ptr addrspace(1) [[CAST1]], i16 8812; CHECK-NEXT:    [[A_SROA_2_0_COPYLOAD:%.*]] = load ptr, ptr addrspace(1) [[A_SROA_2_0_CAST1_SROA_IDX]], align 1813; 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 0820  %val = load i64, ptr %gep821  ret i64 %val822}823 824define i32 @test20() {825; Ensure we can track negative offsets (before the beginning of the alloca) and826; 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, 2831; CHECK-NEXT:    [[SUM2:%.*]] = add i32 [[SUM1]], 3832; CHECK-NEXT:    ret i32 [[SUM2]]833;834entry:835  %a = alloca [3 x i32]836  store i32 1, ptr %a837  %gep2.1 = getelementptr [3 x i32], ptr %a, i32 0, i32 -2838  %gep2.2 = getelementptr i32, ptr %gep2.1, i32 3839  store i32 2, ptr %gep2.2840  %gep3.1 = getelementptr [3 x i32], ptr %a, i32 0, i32 14841  %gep3.2 = getelementptr i32, ptr %gep3.1, i32 -12842  store i32 3, ptr %gep3.2843 844  %load1 = load i32, ptr %a845  %load2 = load i32, ptr %gep2.2846  %load3 = load i32, ptr %gep3.2847  %sum1 = add i32 %load1, %load2848  %sum2 = add i32 %sum1, %load3849  ret i32 %sum2850}851 852declare void @llvm.memset.p0.i64(ptr nocapture, i8, i64, i1) nounwind853 854define i8 @test21() {855; Test allocations and offsets which border on overflow of the int64_t used856; internally. This is really awkward to really test as LLVM doesn't really857; support such extreme constructs cleanly.858;859; CHECK-LABEL: @test21(860; CHECK-NEXT:  entry:861; CHECK-NEXT:    [[RESULT:%.*]] = or i8 -1, -1862; CHECK-NEXT:    ret i8 [[RESULT]]863;864entry:865  %a = alloca [2305843009213693951 x i8]866  %gep0 = getelementptr [2305843009213693951 x i8], ptr %a, i64 0, i64 2305843009213693949867  store i8 255, ptr %gep0868  %gep1 = getelementptr [2305843009213693951 x i8], ptr %a, i64 0, i64 -9223372036854775807869  %gep2 = getelementptr i8, ptr %gep1, i64 -1870  call void @llvm.memset.p0.i64(ptr %gep2, i8 0, i64 18446744073709551615, i1 false)871  %gep3 = getelementptr i8, ptr %gep1, i64 9223372036854775807872  %gep4 = getelementptr i8, ptr %gep3, i64 9223372036854775807873  %gep5 = getelementptr i8, ptr %gep4, i64 -6917529027641081857874  store i8 255, ptr %gep5875  store i32 0, ptr %gep4876  %load = load i8, ptr %gep0877  %gep6 = getelementptr i8, ptr %gep0, i32 1878  %load2 = load i8, ptr %gep6879  %result = or i8 %load, %load2880  ret i8 %result881}882 883%PR13916.struct = type { i8 }884 885define void @PR13916.1() {886; Ensure that we handle overlapping memcpy intrinsics correctly, especially in887; 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 void892;893entry:894  %a = alloca i8895  call void @llvm.memcpy.p0.p0.i32(ptr %a, ptr %a, i32 1, i1 false)896  %tmp2 = load i8, ptr %a897  ret void898}899 900define void @PR13916.2(i1 %c1) {901; Check whether we continue to handle them correctly when they start off with902; different pointer value chains, but during rewriting we coalesce them into the903; 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 void912;913entry:914  %a = alloca %PR13916.struct, align 1915  br i1 %c1, label %if.then, label %if.end916 917if.then:918  call void @llvm.memcpy.p0.p0.i32(ptr %a, ptr %a, i32 1, i1 false)919  br label %if.end920 921if.end:922  %tmp2 = load i8, ptr %a923  ret void924}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 other928; alloca to become dead and get deleted. This might crash or fail under929; 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:    unreachable940; CHECK:       bb4:941; CHECK-NEXT:    unreachable942;943entry:944  %tmp1 = alloca ptr945  %tmp2 = alloca ptr946  br i1 %c1, label %bb1, label %bb2947 948bb1:949  store ptr %ptr, ptr %tmp2950  br i1 %c2, label %bb2, label %bb3951 952bb2:953  %tmp50 = select i1 %c3, ptr %tmp2, ptr %tmp1954  br i1 %c4, label %bb3, label %bb4955 956bb3:957  unreachable958 959bb4:960  unreachable961}962 963define double @PR13969(double %x) {964; Check that we detect when promotion will un-escape an alloca and iterate to965; re-try running SROA over that alloca. Without that, the two allocas that are966; 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 double974  %b = alloca ptr975  %c = alloca double976 977  store double %x, ptr %a978  store ptr %c, ptr %b979  store ptr %a, ptr %b980  store double %x, ptr %c981  %ret = load double, ptr %a982 983  ret double %ret984}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, and991; subsequently crashed (under valgrind) before we fixed the PR. The important992; 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 8997; 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 void999;1000entry:1001  %a = alloca %PR14034.struct1002  %list = getelementptr %PR14034.struct, ptr %a, i32 0, i32 21003  %prev = getelementptr %PR14034.list, ptr %list, i32 0, i32 11004  store ptr %ptr, ptr %prev1005  call void @llvm.memcpy.p0.p0.i32(ptr %ptr2, ptr %a, i32 12, i1 false)1006  ret void1007}1008 1009define i32 @test22(i32 %x) {1010; Test that SROA and promotion is not confused by a grab bax mixture of pointer1011; 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, 01016; CHECK-NEXT:    [[WRAP1_FCA_0_0_EXTRACT:%.*]] = extractvalue [1 x { i32 }] [[WRAP1]], 0, 01017; CHECK-NEXT:    [[TMP0:%.*]] = bitcast i32 [[WRAP1_FCA_0_0_EXTRACT]] to float1018; CHECK-NEXT:    [[LOAD1_FCA_0_0_0_INSERT:%.*]] = insertvalue { [1 x { float }] } poison, float [[TMP0]], 0, 0, 01019; CHECK-NEXT:    [[UNWRAP1:%.*]] = extractvalue { [1 x { float }] } [[LOAD1_FCA_0_0_0_INSERT]], 0, 01020; CHECK-NEXT:    [[WRAP2:%.*]] = insertvalue { {}, { float }, [0 x i8] } poison, { float } [[UNWRAP1]], 11021; CHECK-NEXT:    [[WRAP2_FCA_1_0_EXTRACT:%.*]] = extractvalue { {}, { float }, [0 x i8] } [[WRAP2]], 1, 01022; CHECK-NEXT:    [[TMP1:%.*]] = bitcast float [[WRAP2_FCA_1_0_EXTRACT]] to <4 x i8>1023; CHECK-NEXT:    [[VALCAST1:%.*]] = bitcast <4 x i8> [[TMP1]] to i321024; CHECK-NEXT:    [[WRAP3:%.*]] = insertvalue [1 x [1 x i32]] poison, i32 [[VALCAST1]], 0, 01025; CHECK-NEXT:    [[WRAP4:%.*]] = insertvalue { [1 x [1 x i32]], {} } poison, [1 x [1 x i32]] [[WRAP3]], 01026; CHECK-NEXT:    [[WRAP4_FCA_0_0_0_EXTRACT:%.*]] = extractvalue { [1 x [1 x i32]], {} } [[WRAP4]], 0, 0, 01027; 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 float1029; CHECK-NEXT:    [[LOAD4_FCA_1_INSERT:%.*]] = insertvalue { {}, float, {} } poison, float [[TMP3]], 11030; CHECK-NEXT:    [[UNWRAP2:%.*]] = extractvalue { {}, float, {} } [[LOAD4_FCA_1_INSERT]], 11031; CHECK-NEXT:    [[VALCAST2:%.*]] = bitcast float [[UNWRAP2]] to i321032; 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, 01040  store [1 x { i32 }] %wrap1, ptr %a11041 1042  %load1 = load { [1 x { float }] }, ptr %a11043  %unwrap1 = extractvalue { [1 x { float }] } %load1, 0, 01044 1045  %wrap2 = insertvalue { {}, { float }, [0 x i8] } poison, { float } %unwrap1, 11046  store { {}, { float }, [0 x i8] } %wrap2, ptr %a21047 1048  %gep3 = getelementptr { {}, { float }, [0 x i8] }, ptr %a2, i32 0, i32 1, i32 01049  %load3 = load <4 x i8>, ptr %gep31050  %valcast1 = bitcast <4 x i8> %load3 to i321051 1052  %wrap3 = insertvalue [1 x [1 x i32]] poison, i32 %valcast1, 0, 01053  %wrap4 = insertvalue { [1 x [1 x i32]], {} } poison, [1 x [1 x i32]] %wrap3, 01054  %gep4 = getelementptr { [0 x i8], { [0 x double], [1 x [1 x <4 x i8>]], {} }, { { {} } } }, ptr %a3, i32 0, i32 11055  store { [1 x [1 x i32]], {} } %wrap4, ptr %gep41056 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 01058  %load4 = load { {}, float, {} }, ptr %gep51059  %unwrap2 = extractvalue { {}, float, {} } %load4, 11060  %valcast2 = bitcast float %unwrap2 to i321061 1062  ret i32 %valcast21063}1064 1065define void @PR14059.1(ptr %d) {1066; In PR14059 a peculiar construct was identified as something that is used1067; pervasively in ARM's ABI-calling-convention lowering: the passing of a struct1068; of doubles via an array of i32 in order to place the data into integer1069; registers. This in turn was missed as an optimization by SROA due to the1070; partial loads and stores of integers to the double alloca we were trying to1071; form and promote. The solution is to widen the integer operations to be1072; whole-alloca operations, and perform the appropriate bitcasting on the1073; *values* rather than the pointers. When this works, partial reads and writes1074; via integers can be promoted away.1075;1076; CHECK-LABEL: @PR14059.1(1077; CHECK-NEXT:  entry:1078; CHECK-NEXT:    [[TMP0:%.*]] = bitcast double undef to i641079; CHECK-NEXT:    [[X_SROA_0_I_0_INSERT_MASK:%.*]] = and i64 [[TMP0]], -42949672961080; CHECK-NEXT:    [[X_SROA_0_I_0_INSERT_INSERT:%.*]] = or i64 [[X_SROA_0_I_0_INSERT_MASK]], 01081; CHECK-NEXT:    [[TMP1:%.*]] = bitcast i64 [[X_SROA_0_I_0_INSERT_INSERT]] to double1082; CHECK-NEXT:    [[TMP2:%.*]] = bitcast double [[TMP1]] to i641083; CHECK-NEXT:    [[X_SROA_0_I_2_INSERT_MASK:%.*]] = and i64 [[TMP2]], -2814749766451211084; CHECK-NEXT:    [[X_SROA_0_I_2_INSERT_INSERT:%.*]] = or i64 [[X_SROA_0_I_2_INSERT_MASK]], 01085; CHECK-NEXT:    [[TMP3:%.*]] = bitcast i64 [[X_SROA_0_I_2_INSERT_INSERT]] to double1086; CHECK-NEXT:    [[TMP4:%.*]] = bitcast double [[TMP3]] to i641087; CHECK-NEXT:    [[X_SROA_0_I_4_COPYLOAD:%.*]] = load i32, ptr [[D:%.*]], align 11088; CHECK-NEXT:    [[TMP5:%.*]] = bitcast double 0.000000e+00 to i641089; CHECK-NEXT:    [[X_SROA_0_I_4_INSERT_EXT:%.*]] = zext i32 [[X_SROA_0_I_4_COPYLOAD]] to i641090; CHECK-NEXT:    [[X_SROA_0_I_4_INSERT_SHIFT:%.*]] = shl i64 [[X_SROA_0_I_4_INSERT_EXT]], 321091; CHECK-NEXT:    [[X_SROA_0_I_4_INSERT_MASK3:%.*]] = and i64 [[TMP5]], 42949672951092; 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 double1094; CHECK-NEXT:    [[TMP7:%.*]] = bitcast double [[TMP6]] to i641095; CHECK-NEXT:    [[X_SROA_0_I_4_INSERT_MASK:%.*]] = and i64 [[TMP7]], 42949672951096; CHECK-NEXT:    [[X_SROA_0_I_4_INSERT_INSERT:%.*]] = or i64 [[X_SROA_0_I_4_INSERT_MASK]], 46071824188000174081097; CHECK-NEXT:    [[TMP8:%.*]] = bitcast i64 [[X_SROA_0_I_4_INSERT_INSERT]] to double1098; CHECK-NEXT:    [[ACCUM_REAL_I:%.*]] = load double, ptr [[D]], align 81099; CHECK-NEXT:    [[ADD_R_I:%.*]] = fadd double [[ACCUM_REAL_I]], [[TMP8]]1100; CHECK-NEXT:    store double [[ADD_R_I]], ptr [[D]], align 81101; CHECK-NEXT:    ret void1102;1103entry:1104  %X.sroa.0.i = alloca double, align 81105  call void @llvm.lifetime.start.p0(ptr %X.sroa.0.i)1106 1107  ; Store to the low 32-bits...1108  store i32 0, ptr %X.sroa.0.i, align 81109 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 21112  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 41119  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 41123 1124  ; Do the actual math...1125  %X.sroa.0.0.load1.i = load double, ptr %X.sroa.0.i, align 81126  %accum.real.i = load double, ptr %d, align 81127  %add.r.i = fadd double %accum.real.i, %X.sroa.0.0.load1.i1128  store double %add.r.i, ptr %d, align 81129  call void @llvm.lifetime.end.p0(ptr %X.sroa.0.i)1130  ret void1131}1132 1133define i64 @PR14059.2(ptr %phi) {1134; Check that SROA can split up alloca-wide integer loads and stores where the1135; underlying alloca has smaller components that are accessed independently. This1136; shows up particularly with ABI lowering patterns coming out of Clang that rely1137; 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 01142; CHECK-NEXT:    [[PHI_REAL:%.*]] = load float, ptr [[PHI_REALP]], align 41143; CHECK-NEXT:    [[PHI_IMAGP:%.*]] = getelementptr inbounds { float, float }, ptr [[PHI]], i32 0, i32 11144; CHECK-NEXT:    [[PHI_IMAG:%.*]] = load float, ptr [[PHI_IMAGP]], align 41145; CHECK-NEXT:    [[TMP0:%.*]] = bitcast float [[PHI_REAL]] to i321146; CHECK-NEXT:    [[TMP1:%.*]] = bitcast float [[PHI_IMAG]] to i321147; CHECK-NEXT:    [[RETVAL_SROA_3_0_INSERT_EXT:%.*]] = zext i32 [[TMP1]] to i641148; CHECK-NEXT:    [[RETVAL_SROA_3_0_INSERT_SHIFT:%.*]] = shl i64 [[RETVAL_SROA_3_0_INSERT_EXT]], 321149; CHECK-NEXT:    [[RETVAL_SROA_3_0_INSERT_MASK:%.*]] = and i64 undef, 42949672951150; 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 i641152; CHECK-NEXT:    [[RETVAL_SROA_0_0_INSERT_MASK:%.*]] = and i64 [[RETVAL_SROA_3_0_INSERT_INSERT]], -42949672961153; 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 41158 1159  store i64 0, ptr %retval1160 1161  %phi.realp = getelementptr inbounds { float, float }, ptr %phi, i32 0, i32 01162  %phi.real = load float, ptr %phi.realp1163  %phi.imagp = getelementptr inbounds { float, float }, ptr %phi, i32 0, i32 11164  %phi.imag = load float, ptr %phi.imagp1165 1166  %real = getelementptr inbounds { float, float }, ptr %retval, i32 0, i32 01167  %imag = getelementptr inbounds { float, float }, ptr %retval, i32 0, i32 11168  store float %phi.real, ptr %real1169  store float %phi.imag, ptr %imag1170 1171  %0 = load i64, ptr %retval, align 11172  ret i64 %01173}1174 1175define void @PR14105(ptr %ptr) {1176; Ensure that when rewriting the GEP index '-1' for this alloca we preserve is1177; sign as negative. We use a volatile memcpy to ensure promotion never actually1178; occurs.1179;1180; CHECK-LABEL: @PR14105(1181; CHECK-NEXT:  entry:1182; CHECK-NEXT:    [[A_SROA_0:%.*]] = alloca [16 x i8], align 81183; CHECK-NEXT:    [[GEP:%.*]] = getelementptr inbounds { [16 x i8] }, ptr [[PTR:%.*]], i64 -11184; 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 void1186;1187entry:1188  %a = alloca { [16 x i8] }, align 81189 1190  %gep = getelementptr inbounds { [16 x i8] }, ptr %ptr, i64 -11191 1192  call void @llvm.memcpy.p0.p0.i32(ptr align 8 %gep, ptr align 8 %a, i32 16, i1 true)1193  ret void1194}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 81202; CHECK-NEXT:    [[GEP:%.*]] = getelementptr inbounds { [16 x i8] }, ptr addrspace(1) [[PTR:%.*]], i64 -11203; 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 void1205;1206entry:1207  %a = alloca { [16 x i8] }, align 81208  %gep = getelementptr inbounds { [16 x i8] }, ptr addrspace(1) %ptr, i64 -11209  call void @llvm.memcpy.p1.p0.i32(ptr addrspace(1) align 8 %gep, ptr align 8 %a, i32 16, i1 true)1210  ret void1211}1212 1213define void @PR14465() {1214; Ensure that we don't crash when analyzing a alloca larger than the maximum1215; 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 161219; CHECK-NEXT:    call void @llvm.memset.p0.i64(ptr align 16 [[STACK]], i8 -2, i64 4194304, i1 false)1220; CHECK-NEXT:    ret void1221;1222  %stack = alloca [1048576 x i32], align 161223  call void @llvm.memset.p0.i64(ptr align 16 %stack, i8 -2, i64 4194304, i1 false)1224  ret void1225}1226 1227define void @PR14548(i1 %x) {1228; Handle a mixture of i1 and i8 loads and stores to allocas. This particular1229; pattern caused crashes and invalid output in the PR, and its nature will1230; trigger a mixture in several permutations as we resolve each alloca1231; 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 81238; CHECK-NEXT:    [[B_SROA_0:%.*]] = alloca i8, align 81239; CHECK-NEXT:    store i1 [[X:%.*]], ptr [[B_SROA_0]], align 81240; CHECK-NEXT:    [[B_SROA_0_0_B_SROA_0_0_FOO:%.*]] = load i8, ptr [[B_SROA_0]], align 81241; CHECK-NEXT:    [[B_SROA_0_0_B_SROA_0_0_COPYLOAD:%.*]] = load i8, ptr [[B_SROA_0]], align 81242; CHECK-NEXT:    store i8 [[B_SROA_0_0_B_SROA_0_0_COPYLOAD]], ptr [[A_SROA_0]], align 81243; CHECK-NEXT:    [[A_SROA_0_0_A_SROA_0_0_BAR:%.*]] = load i8, ptr [[A_SROA_0]], align 81244; CHECK-NEXT:    [[A_SROA_0_0_A_SROA_0_0_BAZ:%.*]] = load i1, ptr [[A_SROA_0]], align 81245; CHECK-NEXT:    ret void1246;1247entry:1248  %a = alloca <{ i1 }>, align 81249  %b = alloca <{ i1 }>, align 81250 1251  store i1 %x, ptr %b, align 81252  %foo = load i8, ptr %b, align 11253 1254  call void @llvm.memcpy.p0.p0.i32(ptr %a, ptr %b, i32 1, i1 false) nounwind1255  %bar = load i8, ptr %a, align 11256  %baz = load i1, ptr %a, align 11257 1258  ret void1259}1260 1261define <3 x i8> @PR14572.1(i32 %x) {1262; Ensure that a split integer store which is wider than the type size of the1263; 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 i241268; 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]], 241270; CHECK-NEXT:    [[A_SROA_2_0_EXTRACT_TRUNC:%.*]] = trunc i32 [[A_SROA_2_0_EXTRACT_SHIFT]] to i81271; CHECK-NEXT:    ret <3 x i8> [[TMP0]]1272;1273entry:1274  %a = alloca <3 x i8>, align 41275 1276  store i32 %x, ptr %a, align 11277  %y = load <3 x i8>, ptr %a, align 41278  ret <3 x i8> %y1279}1280 1281define i32 @PR14572.2(<3 x i8> %x) {1282; Ensure that a split integer load which is wider than the type size of the1283; 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 i241288; CHECK-NEXT:    [[A_SROA_2_0_INSERT_EXT:%.*]] = zext i8 undef to i321289; CHECK-NEXT:    [[A_SROA_2_0_INSERT_SHIFT:%.*]] = shl i32 [[A_SROA_2_0_INSERT_EXT]], 241290; CHECK-NEXT:    [[A_SROA_2_0_INSERT_MASK:%.*]] = and i32 undef, 167772151291; 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 i321293; CHECK-NEXT:    [[A_0_INSERT_MASK:%.*]] = and i32 [[A_SROA_2_0_INSERT_INSERT]], -167772161294; 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 41299 1300  store <3 x i8> %x, ptr %a, align 11301  %y = load i32, ptr %a, align 41302  ret i32 %y1303}1304 1305define i32 @PR14601(i32 %x) {1306; Don't try to form a promotable integer alloca when there is a variable length1307; memory intrinsic.1308;1309; CHECK-LABEL: @PR14601(1310; CHECK-NEXT:  entry:1311; CHECK-NEXT:    [[A:%.*]] = alloca i32, align 41312; 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 41314; CHECK-NEXT:    ret i32 [[A_0_V]]1315;1316entry:1317  %a = alloca i321318 1319  call void @llvm.memset.p0.i32(ptr %a, i8 0, i32 %x, i1 false)1320  %v = load i32, ptr %a1321  ret i32 %v1322}1323 1324define void @PR15674(ptr %data, ptr %src, i32 %size) {1325; Arrange (via control flow) to have unmerged stores of a particular width to1326; an alloca where we incrementally store from the end of the array toward the1327; beginning of the array. Ensure that the final integer store, despite being1328; 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 41334; 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 31342; CHECK-NEXT:    [[SRC_3:%.*]] = load i8, ptr [[SRC_GEP3]], align 11343; CHECK-NEXT:    [[TMP_SROA_0_3_TMP_GEP3_SROA_IDX3:%.*]] = getelementptr inbounds i8, ptr [[TMP_SROA_0]], i64 31344; CHECK-NEXT:    store i8 [[SRC_3]], ptr [[TMP_SROA_0_3_TMP_GEP3_SROA_IDX3]], align 11345; CHECK-NEXT:    br label [[BB3]]1346; CHECK:       bb3:1347; CHECK-NEXT:    [[SRC_GEP2:%.*]] = getelementptr inbounds i8, ptr [[SRC]], i32 21348; CHECK-NEXT:    [[SRC_2:%.*]] = load i8, ptr [[SRC_GEP2]], align 11349; CHECK-NEXT:    [[TMP_SROA_0_2_TMP_GEP2_SROA_IDX2:%.*]] = getelementptr inbounds i8, ptr [[TMP_SROA_0]], i64 21350; CHECK-NEXT:    store i8 [[SRC_2]], ptr [[TMP_SROA_0_2_TMP_GEP2_SROA_IDX2]], align 21351; CHECK-NEXT:    br label [[BB2]]1352; CHECK:       bb2:1353; CHECK-NEXT:    [[SRC_GEP1:%.*]] = getelementptr inbounds i8, ptr [[SRC]], i32 11354; CHECK-NEXT:    [[SRC_1:%.*]] = load i8, ptr [[SRC_GEP1]], align 11355; CHECK-NEXT:    [[TMP_SROA_0_1_TMP_GEP1_SROA_IDX1:%.*]] = getelementptr inbounds i8, ptr [[TMP_SROA_0]], i64 11356; CHECK-NEXT:    store i8 [[SRC_1]], ptr [[TMP_SROA_0_1_TMP_GEP1_SROA_IDX1]], align 11357; CHECK-NEXT:    br label [[BB1]]1358; CHECK:       bb1:1359; CHECK-NEXT:    [[SRC_0:%.*]] = load i8, ptr [[SRC]], align 11360; CHECK-NEXT:    store i8 [[SRC_0]], ptr [[TMP_SROA_0]], align 41361; 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 void1365;1366entry:1367  %tmp = alloca [4 x i8], align 11368 1369  switch i32 %size, label %end [1370  i32 4, label %bb41371  i32 3, label %bb31372  i32 2, label %bb21373  i32 1, label %bb11374  ]1375 1376bb4:1377  %src.gep3 = getelementptr inbounds i8, ptr %src, i32 31378  %src.3 = load i8, ptr %src.gep31379  %tmp.gep3 = getelementptr inbounds [4 x i8], ptr %tmp, i32 0, i32 31380  store i8 %src.3, ptr %tmp.gep31381 1382  br label %bb31383 1384bb3:1385  %src.gep2 = getelementptr inbounds i8, ptr %src, i32 21386  %src.2 = load i8, ptr %src.gep21387  %tmp.gep2 = getelementptr inbounds [4 x i8], ptr %tmp, i32 0, i32 21388  store i8 %src.2, ptr %tmp.gep21389 1390  br label %bb21391 1392bb2:1393  %src.gep1 = getelementptr inbounds i8, ptr %src, i32 11394  %src.1 = load i8, ptr %src.gep11395  %tmp.gep1 = getelementptr inbounds [4 x i8], ptr %tmp, i32 0, i32 11396  store i8 %src.1, ptr %tmp.gep11397 1398  br label %bb11399 1400bb1:1401  %src.0 = load i8, ptr %src1402  store i8 %src.0, ptr %tmp1403 1404  br label %end1405 1406end:1407  call void @llvm.memcpy.p0.p0.i32(ptr %data, ptr %tmp, i32 %size, i1 false)1408  ret void1409}1410 1411define void @PR15805(i1 %a, i1 %b) {1412; CHECK-PRESERVE-CFG-LABEL: @PR15805(1413; CHECK-PRESERVE-CFG-NEXT:    [[C:%.*]] = alloca i64, align 81414; 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 81416; CHECK-PRESERVE-CFG-NEXT:    ret void1417;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 void1425;1426  %c = alloca i64, align 81427  %p.0.c = select i1 %a, ptr %c, ptr %c1428  %cond.in = select i1 %b, ptr %p.0.c, ptr %c1429  %cond = load i64, ptr %cond.in, align 81430  ret void1431}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 inside1435; of looping unreachable code. This helps ensure that we aren't sensitive to the1436; 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 81441; 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 81445; CHECK-PRESERVE-CFG-NEXT:    br i1 [[C2:%.*]], label [[LOOP:%.*]], label [[EXIT]]1446; CHECK-PRESERVE-CFG:       exit:1447; CHECK-PRESERVE-CFG-NEXT:    ret void1448;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 81453; 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 81456; 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 void1462;1463  %c = alloca i64, align 81464  br label %exit1465 1466loop:1467  %cond.in = select i1 %a, ptr %c, ptr %p.0.c1468  %p.0.c = select i1 %b, ptr %c, ptr %c1469  %cond = load i64, ptr %cond.in, align 81470  br i1 %c2, label %loop, label %exit1471 1472exit:1473  ret void1474}1475 1476define void @PR16651.1(ptr %a) {1477; This test case caused a crash due to the volatile memcpy in combination with1478; lowering to integer loads and stores of a width other than that of the original1479; memcpy.1480;1481;1482; CHECK-LABEL: @PR16651.1(1483; CHECK-NEXT:  entry:1484; CHECK-NEXT:    [[B_SROA_0:%.*]] = alloca i16, align 41485; CHECK-NEXT:    [[B_SROA_1:%.*]] = alloca i8, align 21486; CHECK-NEXT:    [[B_SROA_2:%.*]] = alloca i8, align 11487; CHECK-NEXT:    [[B_SROA_0_0_COPYLOAD:%.*]] = load volatile i16, ptr [[A:%.*]], align 41488; CHECK-NEXT:    store volatile i16 [[B_SROA_0_0_COPYLOAD]], ptr [[B_SROA_0]], align 41489; CHECK-NEXT:    [[B_SROA_1_0_A_SROA_IDX:%.*]] = getelementptr inbounds i8, ptr [[A]], i64 21490; CHECK-NEXT:    [[B_SROA_1_0_COPYLOAD:%.*]] = load volatile i8, ptr [[B_SROA_1_0_A_SROA_IDX]], align 21491; CHECK-NEXT:    store volatile i8 [[B_SROA_1_0_COPYLOAD]], ptr [[B_SROA_1]], align 21492; CHECK-NEXT:    [[B_SROA_2_0_A_SROA_IDX:%.*]] = getelementptr inbounds i8, ptr [[A]], i64 31493; CHECK-NEXT:    [[B_SROA_2_0_COPYLOAD:%.*]] = load volatile i8, ptr [[B_SROA_2_0_A_SROA_IDX]], align 11494; CHECK-NEXT:    store volatile i8 [[B_SROA_2_0_COPYLOAD]], ptr [[B_SROA_2]], align 11495; CHECK-NEXT:    [[B_SROA_1_0_B_SROA_1_2_:%.*]] = load i8, ptr [[B_SROA_1]], align 21496; CHECK-NEXT:    unreachable1497;1498entry:1499  %b = alloca i32, align 41500  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 21502  load i8, ptr %b.gep, align 21503  unreachable1504}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 that1508; can't be speculated. It shouldn't be promoted, but we missed that fact when1509; analyzing whether we could form a vector promotion because that code didn't1510; 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 81516; CHECK-PRESERVE-CFG-NEXT:    store <2 x float> [[VAL:%.*]], ptr [[TV1_SROA_0]], align 81517; 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 81519; CHECK-PRESERVE-CFG-NEXT:    ret void1520;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 01524; 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 81527; 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 void1531;1532entry:1533  %tv1 = alloca { <2 x float>, <2 x float> }, align 81534  %0 = getelementptr { <2 x float>, <2 x float> }, ptr %tv1, i64 0, i32 11535  store <2 x float> %val, ptr %0, align 81536  %1 = getelementptr inbounds { <2 x float>, <2 x float> }, ptr %tv1, i64 0, i32 1, i64 01537  %cond105.in.i.i = select i1 %c1, ptr null, ptr %11538  %cond105.i.i = load float, ptr %cond105.in.i.i, align 81539  ret void1540}1541 1542define void @test23(i32 %x) {1543; CHECK-LABEL: @test23(1544; CHECK-NEXT:  entry:1545; CHECK-NEXT:    ret void1546;1547entry:1548  %a = alloca i32, align 41549  store i32 %x, ptr %a, align 41550  %gep1 = getelementptr inbounds i32, ptr %a, i32 11551  call void @llvm.memcpy.p0.p0.i32(ptr %gep1, ptr %a, i32 4, i1 false)1552  ret void1553}1554 1555define void @PR18615(ptr %ptr) {1556; CHECK-LABEL: @PR18615(1557; CHECK-NEXT:  entry:1558; CHECK-NEXT:    ret void1559;1560entry:1561  %f = alloca i81562  %gep = getelementptr i8, ptr %f, i64 -11563  call void @llvm.memcpy.p0.p0.i32(ptr %ptr, ptr %gep, i32 1, i1 false)1564  ret void1565}1566 1567define void @test24(ptr %src, ptr %dst) {1568; CHECK-LABEL: @test24(1569; CHECK-NEXT:  entry:1570; CHECK-NEXT:    [[A:%.*]] = alloca i64, align 161571; 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 void1576;1577entry:1578  %a = alloca i64, align 161579  call void @llvm.memcpy.p0.p0.i32(ptr %a, ptr %src, i32 8, i1 true), !tbaa !01580  call void @llvm.memcpy.p0.p0.i32(ptr %dst, ptr %a, i32 8, i1 true), !tbaa !31581  ret void1582}1583 1584define float @test25() {1585; Check that we split up stores in order to promote the smaller SSA values.. These types1586; of patterns can arise because LLVM maps small memcpy's to integer load and1587; stores. If we get a memcpy of an aggregate (such as C and C++ frontends would1588; produce, but so might any language frontend), this will in many cases turn into1589; an integer load and store. SROA needs to be extremely powerful to correctly1590; 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 float1596; CHECK-NEXT:    [[TMP1:%.*]] = bitcast i32 1065353216 to float1597; CHECK-NEXT:    [[RET:%.*]] = fadd float [[TMP0]], [[TMP1]]1598; CHECK-NEXT:    ret float [[RET]]1599;1600entry:1601  %a = alloca i641602  %b = alloca i641603  %a.gep2 = getelementptr [2 x float], ptr %a, i32 0, i32 11604  %b.gep2 = getelementptr [2 x float], ptr %b, i32 0, i32 11605  store float 0.0, ptr %a1606  store float 1.0, ptr %a.gep21607  %v = load i64, ptr %a1608  store i64 %v, ptr %b1609  %f1 = load float, ptr %b1610  %f2 = load float, ptr %b.gep21611  %ret = fadd float %f1, %f21612  ret float %ret1613}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 41625; CHECK-NEXT:    [[V14:%.*]] = load i32, ptr getelementptr inbounds (i8, ptr @complex1, i64 4), align 41626; CHECK-NEXT:    [[TMP0:%.*]] = bitcast i32 [[V13]] to float1627; CHECK-NEXT:    [[TMP1:%.*]] = bitcast i32 [[V14]] to float1628; CHECK-NEXT:    [[SUM:%.*]] = fadd float [[TMP0]], [[TMP1]]1629; CHECK-NEXT:    [[TMP2:%.*]] = bitcast float [[SUM]] to i321630; CHECK-NEXT:    [[TMP3:%.*]] = bitcast float [[SUM]] to i321631; CHECK-NEXT:    store i32 [[TMP2]], ptr @complex2, align 41632; CHECK-NEXT:    store i32 [[TMP3]], ptr getelementptr inbounds (i8, ptr @complex2, i64 4), align 41633; CHECK-NEXT:    ret void1634;1635entry:1636  %a = alloca i641637  %a.gep2 = getelementptr [2 x float], ptr %a, i32 0, i32 11638  %v1 = load i64, ptr @complex11639  store i64 %v1, ptr %a1640  %f1 = load float, ptr %a1641  %f2 = load float, ptr %a.gep21642  %sum = fadd float %f1, %f21643  store float %sum, ptr %a1644  store float %sum, ptr %a.gep21645  %v2 = load i64, ptr %a1646  store i64 %v2, ptr @complex21647  ret void1648}1649 1650define float @test27() {1651; Another, more complex case of splittable i64 loads and stores. This example1652; is a particularly challenging one because the load and store both point into1653; 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 float1659; CHECK-NEXT:    [[TMP1:%.*]] = bitcast i32 1065353216 to float1660; 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 41666  %gep3 = getelementptr [12 x i8], ptr %a, i32 0, i32 81667  store float 0.0, ptr %a1668  store float 1.0, ptr %gep21669  %v = load i64, ptr %a1670  store i64 %v, ptr %gep21671  %f1 = load float, ptr %gep21672  %f2 = load float, ptr %gep31673  %ret = fadd float %f1, %f21674  ret float %ret1675}1676 1677define i32 @PR22093() {1678; Test that we don't try to pre-split a splittable store of a splittable but1679; not pre-splittable load over the same alloca. We "handle" this case when the1680; load is unsplittable but unrelated to this alloca by just generating extra1681; loads without touching the original, but when the original load was out of1682; this alloca we need to handle it specially to ensure the splits line up1683; properly for rewriting.1684;1685;1686; CHECK-LABEL: @PR22093(1687; CHECK-NEXT:  entry:1688; CHECK-NEXT:    [[A_SROA_0:%.*]] = alloca i16, align 41689; CHECK-NEXT:    store volatile i16 42, ptr [[A_SROA_0]], align 41690; CHECK-NEXT:    [[A_SROA_0_0_A_SROA_0_0_LOAD:%.*]] = load i16, ptr [[A_SROA_0]], align 41691; CHECK-NEXT:    [[A_SROA_3_0_INSERT_EXT:%.*]] = zext i16 undef to i321692; CHECK-NEXT:    [[A_SROA_3_0_INSERT_SHIFT:%.*]] = shl i32 [[A_SROA_3_0_INSERT_EXT]], 161693; CHECK-NEXT:    [[A_SROA_3_0_INSERT_MASK:%.*]] = and i32 undef, 655351694; 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 i321696; CHECK-NEXT:    [[A_SROA_0_0_INSERT_MASK:%.*]] = and i32 [[A_SROA_3_0_INSERT_INSERT]], -655361697; 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 i161699; CHECK-NEXT:    store i16 [[A_SROA_0_0_EXTRACT_TRUNC]], ptr [[A_SROA_0]], align 41700; CHECK-NEXT:    [[A_SROA_3_0_EXTRACT_SHIFT:%.*]] = lshr i32 [[A_SROA_0_0_INSERT_INSERT]], 161701; CHECK-NEXT:    [[A_SROA_3_0_EXTRACT_TRUNC:%.*]] = trunc i32 [[A_SROA_3_0_EXTRACT_SHIFT]] to i161702; CHECK-NEXT:    ret i32 [[A_SROA_0_0_INSERT_INSERT]]1703;1704entry:1705  %a = alloca i321706  store volatile i16 42, ptr %a1707  %load = load i32, ptr %a1708  store i32 %load, ptr %a1709  ret i32 %load1710}1711 1712define void @PR22093.2() {1713; Another way that we end up being unable to split a particular set of loads1714; and stores can even have ordering importance. Here we have a load which is1715; pre-splittable by itself, and the first store is also compatible. But the1716; second store of the load makes the load unsplittable because of a mismatch of1717; splits. Because this makes the load unsplittable, we also have to go back and1718; remove the first store from the presplit candidates as its load won't be1719; presplit.1720;1721;1722; CHECK-LABEL: @PR22093.2(1723; CHECK-NEXT:  entry:1724; CHECK-NEXT:    [[A_SROA_0:%.*]] = alloca i16, align 81725; CHECK-NEXT:    [[A_SROA_31:%.*]] = alloca i8, align 41726; CHECK-NEXT:    store volatile i16 42, ptr [[A_SROA_0]], align 81727; CHECK-NEXT:    [[A_SROA_0_0_A_SROA_0_0_LOAD:%.*]] = load i16, ptr [[A_SROA_0]], align 81728; CHECK-NEXT:    [[A_SROA_3_0_INSERT_EXT:%.*]] = zext i16 undef to i321729; CHECK-NEXT:    [[A_SROA_3_0_INSERT_SHIFT:%.*]] = shl i32 [[A_SROA_3_0_INSERT_EXT]], 161730; CHECK-NEXT:    [[A_SROA_3_0_INSERT_MASK:%.*]] = and i32 undef, 655351731; 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 i321733; CHECK-NEXT:    [[A_SROA_0_0_INSERT_MASK:%.*]] = and i32 [[A_SROA_3_0_INSERT_INSERT]], -655361734; 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 i161736; CHECK-NEXT:    store i16 [[A_SROA_0_0_EXTRACT_TRUNC]], ptr [[A_SROA_0]], align 81737; CHECK-NEXT:    [[A_SROA_3_0_EXTRACT_SHIFT:%.*]] = lshr i32 [[A_SROA_0_0_INSERT_INSERT]], 161738; CHECK-NEXT:    [[A_SROA_3_0_EXTRACT_TRUNC:%.*]] = trunc i32 [[A_SROA_3_0_EXTRACT_SHIFT]] to i161739; CHECK-NEXT:    store volatile i8 13, ptr [[A_SROA_31]], align 41740; CHECK-NEXT:    [[A_SROA_31_4_EXTRACT_TRUNC:%.*]] = trunc i32 [[A_SROA_0_0_INSERT_INSERT]] to i81741; CHECK-NEXT:    store i8 [[A_SROA_31_4_EXTRACT_TRUNC]], ptr [[A_SROA_31]], align 41742; CHECK-NEXT:    [[A_SROA_5_4_EXTRACT_SHIFT:%.*]] = lshr i32 [[A_SROA_0_0_INSERT_INSERT]], 81743; CHECK-NEXT:    [[A_SROA_5_4_EXTRACT_TRUNC:%.*]] = trunc i32 [[A_SROA_5_4_EXTRACT_SHIFT]] to i241744; CHECK-NEXT:    ret void1745;1746entry:1747  %a = alloca i641748  store volatile i16 42, ptr %a1749  %load = load i32, ptr %a1750  store i32 %load, ptr %a1751  %a.gep1 = getelementptr i32, ptr %a, i32 11752  store volatile i8 13, ptr %a.gep11753  store i32 %load, ptr %a.gep11754  ret void1755}1756 1757define void @PR23737() {1758; CHECK-LABEL: @PR23737(1759; CHECK-NEXT:  entry:1760; CHECK-NEXT:    [[PTR:%.*]] = alloca i64, align 81761; CHECK-NEXT:    store atomic volatile i64 0, ptr [[PTR]] seq_cst, align 81762; CHECK-NEXT:    [[PTR_0_LOAD:%.*]] = load atomic volatile i64, ptr [[PTR]] seq_cst, align 81763; CHECK-NEXT:    ret void1764;1765entry:1766  %ptr = alloca i64, align 81767  store atomic volatile i64 0, ptr %ptr seq_cst, align 81768  %load = load atomic volatile i64, ptr %ptr seq_cst, align 81769  ret void1770}1771 1772define i16 @PR24463() {1773; Ensure we can handle a very interesting case where there is an integer-based1774; rewrite of the uses of the alloca, but where one of the integers in that is1775; a sub-integer that requires extraction *and* extends past the end of the1776; 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 i161782; 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 11787  store i16 0, ptr %gep11788  %gep2 = getelementptr inbounds [3 x i8], ptr %alloca, i64 0, i64 21789  %load = load i16, ptr %gep21790  ret i16 %load1791}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 41800; CHECK-NEXT:    [[OUTDATA_SROA_IDX:%.*]] = getelementptr inbounds i8, ptr [[OUTDATA]], i64 41801; CHECK-NEXT:    store i32 1139015680, ptr [[OUTDATA_SROA_IDX]], align 41802; CHECK-NEXT:    [[TMPDATA_SROA_6_0_OUTDATA_SROA_IDX:%.*]] = getelementptr inbounds i8, ptr [[OUTDATA]], i64 81803; CHECK-NEXT:    [[TMPDATA_SROA_6_SROA_4_0_INSERT_EXT:%.*]] = zext i32 1139015680 to i641804; CHECK-NEXT:    [[TMPDATA_SROA_6_SROA_4_0_INSERT_SHIFT:%.*]] = shl i64 [[TMPDATA_SROA_6_SROA_4_0_INSERT_EXT]], 321805; CHECK-NEXT:    [[TMPDATA_SROA_6_SROA_4_0_INSERT_MASK:%.*]] = and i64 undef, 42949672951806; 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 i641808; CHECK-NEXT:    [[TMPDATA_SROA_6_SROA_0_0_INSERT_MASK:%.*]] = and i64 [[TMPDATA_SROA_6_SROA_4_0_INSERT_INSERT]], -42949672961809; 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 41811; CHECK-NEXT:    ret void1812;1813entry:1814  %tmpData = alloca %struct.STest, align 81815  call void @llvm.lifetime.start.p0(ptr %tmpData)1816  store float 1.230000e+02, ptr %tmpData, align 81817  %y = getelementptr inbounds %struct.STest, ptr %tmpData, i64 0, i32 0, i32 11818  store float 4.560000e+02, ptr %y, align 41819  %m_posB = getelementptr inbounds %struct.STest, ptr %tmpData, i64 0, i32 11820  %0 = load i64, ptr %tmpData, align 81821  store i64 %0, ptr %m_posB, align 81822  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(ptr %tmpData)1824  ret void1825}1826 1827declare void @llvm.memcpy.p0.p0.i64(ptr nocapture, ptr nocapture, i64, i1) nounwind1828 1829define void @PR27999() unnamed_addr {1830; CHECK-LABEL: @PR27999(1831; CHECK-NEXT:  entry-block:1832; CHECK-NEXT:    ret void1833;1834entry-block:1835  %0 = alloca [2 x i64], align 81836  call void @llvm.lifetime.start.p0(ptr %0)1837  call void @llvm.lifetime.end.p0(ptr %0)1838  ret void1839}1840 1841define void @PR29139() {1842; CHECK-LABEL: @PR29139(1843; CHECK-NEXT:  bb1:1844; CHECK-NEXT:    ret void1845;1846bb1:1847  %e.7.sroa.6.i = alloca i32, align 11848  %e.7.sroa.6.0.load81.i = load i32, ptr %e.7.sroa.6.i, align 11849  call void @llvm.lifetime.end.p0(ptr %e.7.sroa.6.i)1850  ret void1851}1852 1853; PR35657 reports assertion failure with this code1854define void @PR35657(i64 %v) {1855; CHECK-LABEL: @PR35657(1856; CHECK-NEXT:  entry:1857; CHECK-NEXT:    [[A48_SROA_0_0_EXTRACT_TRUNC:%.*]] = trunc i64 [[V:%.*]] to i161858; CHECK-NEXT:    [[A48_SROA_2_0_EXTRACT_SHIFT:%.*]] = lshr i64 [[V]], 161859; CHECK-NEXT:    [[A48_SROA_2_0_EXTRACT_TRUNC:%.*]] = trunc i64 [[A48_SROA_2_0_EXTRACT_SHIFT]] to i481860; CHECK-NEXT:    call void @callee16(i16 [[A48_SROA_0_0_EXTRACT_TRUNC]])1861; CHECK-NEXT:    call void @callee48(i48 [[A48_SROA_2_0_EXTRACT_TRUNC]])1862; CHECK-NEXT:    ret void1863;1864entry:1865  %a48 = alloca i481866  store i64 %v, ptr %a481867  %b0_15 = load i16, ptr %a481868  %a48_offset2 = getelementptr inbounds i8, ptr %a48, i64 21869  %b16_63 = load i48, ptr %a48_offset2, align 21870  call void @callee16(i16 %b0_15)1871  call void @callee48(i48 %b16_63)1872  ret void1873}1874 1875declare void @callee16(i16 %a)1876declare void @callee48(i48 %a)1877 1878define void @test28(i64 %v) #0 {1879; SROA should split the first i64 store to avoid additional and/or instructions1880; when storing into i32 fields1881;1882; CHECK-LABEL: @test28(1883; CHECK-NEXT:  entry:1884; CHECK-NEXT:    [[T_SROA_0_8_EXTRACT_TRUNC:%.*]] = trunc i64 [[V:%.*]] to i321885; CHECK-NEXT:    [[T_SROA_2_8_EXTRACT_SHIFT:%.*]] = lshr i64 [[V]], 321886; CHECK-NEXT:    [[T_SROA_2_8_EXTRACT_TRUNC:%.*]] = trunc i64 [[T_SROA_2_8_EXTRACT_SHIFT]] to i321887; CHECK-NEXT:    ret void1888;1889entry:1890  %t = alloca { i64, i32, i32 }1891 1892  %b = getelementptr { i64, i32, i32 }, ptr %t, i32 0, i32 11893  store i64 %v, ptr %b1894 1895  %0 = load i32, ptr %b1896  %c = getelementptr { i64, i32, i32 }, ptr %t, i32 0, i32 21897  store i32 %0, ptr %c1898  ret void1899}1900 1901declare void @llvm.lifetime.start.isVoid.i64.p0(ptr nocapture)1902declare void @llvm.lifetime.end.isVoid.i64.p0(ptr nocapture)1903@array = dso_local global [10 x float] zeroinitializer, align 41904 1905define void @test29(i32 %num, i32 %tid) {1906; CHECK-LABEL: @test29(1907; CHECK-NEXT:  entry:1908; CHECK-NEXT:    [[CMP1:%.*]] = icmp sgt i32 [[NUM:%.*]], 01909; CHECK-NEXT:    br i1 [[CMP1]], label [[BB1:%.*]], label [[BB7:%.*]]1910; CHECK:       bb1:1911; CHECK-NEXT:    [[TOBOOL:%.*]] = icmp eq i32 [[TID:%.*]], 01912; CHECK-NEXT:    [[CONV_I:%.*]] = zext i32 [[TID]] to i641913; CHECK-NEXT:    [[ARRAYIDX5:%.*]] = getelementptr inbounds [10 x float], ptr @array, i64 0, i64 [[CONV_I]]1914; CHECK-NEXT:    br label [[BB2:%.*]]1915; CHECK:       bb2:1916; CHECK-NEXT:    [[I_02:%.*]] = phi i32 [ [[NUM]], [[BB1]] ], [ [[SUB:%.*]], [[BB5:%.*]] ]1917; CHECK-NEXT:    br i1 [[TOBOOL]], label [[BB3:%.*]], label [[BB4:%.*]]1918; CHECK:       bb3:1919; CHECK-NEXT:    br label [[BB5]]1920; CHECK:       bb4:1921; CHECK-NEXT:    store i32 undef, ptr [[ARRAYIDX5]], align 41922; CHECK-NEXT:    br label [[BB5]]1923; CHECK:       bb5:1924; CHECK-NEXT:    [[SUB]] = add i32 [[I_02]], -11925; CHECK-NEXT:    [[CMP:%.*]] = icmp sgt i32 [[SUB]], 01926; CHECK-NEXT:    br i1 [[CMP]], label [[BB2]], label [[BB6:%.*]]1927; CHECK:       bb6:1928; CHECK-NEXT:    br label [[BB7]]1929; CHECK:       bb7:1930; CHECK-NEXT:    ret void1931;1932entry:1933  %ra = alloca [10 x float], align 41934  call void @llvm.lifetime.start.isVoid.i64.p0(ptr nonnull %ra)1935 1936  %cmp1 = icmp sgt i32 %num, 01937  br i1 %cmp1, label %bb1, label %bb71938 1939bb1:1940  %tobool = icmp eq i32 %tid, 01941  %conv.i = zext i32 %tid to i641942  %0 = load i32, ptr %ra, align 41943  %arrayidx5 = getelementptr inbounds [10 x float], ptr @array, i64 0, i64 %conv.i1944  br label %bb21945 1946bb2:1947  %i.02 = phi i32 [ %num, %bb1 ], [ %sub, %bb5 ]1948  br i1 %tobool, label %bb3, label %bb41949 1950bb3:1951  br label %bb51952 1953bb4:1954  store i32 %0, ptr %arrayidx5, align 41955  br label %bb51956 1957bb5:1958  %sub = add i32 %i.02, -11959  %cmp = icmp sgt i32 %sub, 01960  br i1 %cmp, label %bb2, label %bb61961 1962bb6:1963  br label %bb71964 1965bb7:1966  call void @llvm.lifetime.end.isVoid.i64.p0(ptr nonnull %ra)1967  ret void1968}1969 1970define i32 @load_atomic_volatile_past_end() {1971; CHECK-LABEL: @load_atomic_volatile_past_end(1972; CHECK-NEXT:    [[A:%.*]] = alloca i1, align 11973; CHECK-NEXT:    [[A_0_V:%.*]] = load atomic volatile i32, ptr [[A]] seq_cst, align 11974; CHECK-NEXT:    ret i32 [[A_0_V]]1975;1976  %a = alloca i1, align 11977  %v = load atomic volatile i32, ptr %a seq_cst, align 41978  ret i32 %v1979}1980 1981define i32 @load_volatile_past_end() {1982; CHECK-LABEL: @load_volatile_past_end(1983; CHECK-NEXT:    [[A:%.*]] = alloca i1, align 11984; CHECK-NEXT:    [[A_0_V:%.*]] = load volatile i32, ptr [[A]], align 11985; CHECK-NEXT:    ret i32 [[A_0_V]]1986;1987  %a = alloca i1, align 11988  %v = load volatile i32, ptr %a, align 41989  ret i32 %v1990}1991 1992define i32 @load_atomic_past_end() {1993; CHECK-LABEL: @load_atomic_past_end(1994; CHECK-NEXT:    [[A_0_LOAD_EXT:%.*]] = zext i1 undef to i321995; CHECK-NEXT:    ret i32 [[A_0_LOAD_EXT]]1996;1997  %a = alloca i1, align 11998  %v = load atomic i32, ptr %a seq_cst, align 41999  ret i32 %v2000}2001 2002!0 = !{!1, !1, i64 0, i64 200}2003!1 = !{!2, i64 1, !"type_0"}2004!2 = !{!"root"}2005!3 = !{!4, !4, i64 0, i64 1}2006!4 = !{!2, i64 1, !"type_3"}2007!5 = !{!6, !6, i64 0, i64 1}2008!6 = !{!2, i64 1, !"type_5"}2009!7 = !{!8, !8, i64 0, i64 1}2010!8 = !{!2, i64 1, !"type_7"}2011!9 = !{!10, !10, i64 0, i64 1}2012!10 = !{!2, i64 1, !"type_9"}2013!11 = !{!12, !12, i64 0, i64 1}2014!12 = !{!2, i64 1, !"type_11"}2015!13 = !{!14, !14, i64 0, i64 1}2016!14 = !{!2, i64 1, !"type_13"}2017!15 = !{!16, !16, i64 0, i64 1}2018!16 = !{!2, i64 1, !"type_15"}2019!17 = !{!18, !18, i64 0, i64 1}2020!18 = !{!2, i64 1, !"type_17"}2021!19 = !{!20, !20, i64 0, i64 1}2022!20 = !{!2, i64 1, !"type_19"}2023!21 = !{!22, !22, i64 0, i64 1}2024!22 = !{!2, i64 1, !"type_21"}2025!23 = !{!24, !24, i64 0, i64 1}2026!24 = !{!2, i64 1, !"type_23"}2027!25 = !{!26, !26, i64 0, i64 1}2028!26 = !{!2, i64 1, !"type_25"}2029!27 = !{!28, !28, i64 0, i64 1}2030!28 = !{!2, i64 1, !"type_27"}2031!29 = !{!30, !30, i64 0, i64 1}2032!30 = !{!2, i64 1, !"type_29"}2033!31 = !{!32, !32, i64 0, i64 1}2034!32 = !{!2, i64 1, !"type_31"}2035!33 = !{!34, !34, i64 0, i64 1}2036!34 = !{!2, i64 1, !"type_33"}2037!35 = !{!36, !36, i64 0, i64 1}2038!36 = !{!2, i64 1, !"type_35"}2039!37 = !{!38, !38, i64 0, i64 1}2040!38 = !{!2, i64 1, !"type_37"}2041!39 = !{!40, !40, i64 0, i64 1}2042!40 = !{!2, i64 1, !"type_39"}2043!41 = !{!42, !42, i64 0, i64 1}2044!42 = !{!2, i64 1, !"type_41"}2045!43 = !{!44, !44, i64 0, i64 1}2046!44 = !{!2, i64 1, !"type_43"}2047!45 = !{!46, !46, i64 0, i64 1}2048!46 = !{!2, i64 1, !"type_45"}2049!47 = !{!48, !48, i64 0, i64 1}2050!48 = !{!2, i64 1, !"type_47"}2051!49 = !{!50, !50, i64 0, i64 1}2052!50 = !{!2, i64 1, !"type_49"}2053!51 = !{!52, !52, i64 0, i64 1}2054!52 = !{!2, i64 1, !"type_51"}2055!53 = !{!54, !54, i64 0, i64 1}2056!54 = !{!2, i64 1, !"type_53"}2057!55 = !{!56, !56, i64 0, i64 1}2058!56 = !{!2, i64 1, !"type_55"}2059!57 = !{!58, !58, i64 0, i64 1}2060!58 = !{!2, i64 1, !"type_57"}2061!59 = !{!60, !60, i64 0, i64 1}2062!60 = !{!2, i64 1, !"type_59"}2063 2064 2065 2066 2067 2068 2069 2070 2071 2072 2073