1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py 2; RUN: opt -S -sroa < %s | FileCheck %s 3 4%pair = type { i32, i32 } 5 6define i32 @test_sroa_select_gep(i1 %cond) { 7; CHECK-LABEL: @test_sroa_select_gep( 8; CHECK-NEXT: bb: 9; CHECK-NEXT: [[LOAD_SROA_SPECULATED:%.*]] = select i1 [[COND:%.*]], i32 1, i32 2 10; CHECK-NEXT: ret i32 [[LOAD_SROA_SPECULATED]] 11; 12bb: 13 %a = alloca %pair, align 4 14 %b = alloca %pair, align 4 15 %gep_a = getelementptr inbounds %pair, %pair* %a, i32 0, i32 1 16 %gep_b = getelementptr inbounds %pair, %pair* %b, i32 0, i32 1 17 store i32 1, i32* %gep_a, align 4 18 store i32 2, i32* %gep_b, align 4 19 %select = select i1 %cond, %pair* %a, %pair* %b 20 %gep = getelementptr inbounds %pair, %pair* %select, i32 0, i32 1 21 %load = load i32, i32* %gep, align 4 22 ret i32 %load 23} 24 25define i32 @test_sroa_select_gep_non_inbound(i1 %cond) { 26; CHECK-LABEL: @test_sroa_select_gep_non_inbound( 27; CHECK-NEXT: bb: 28; CHECK-NEXT: [[LOAD_SROA_SPECULATED:%.*]] = select i1 [[COND:%.*]], i32 1, i32 2 29; CHECK-NEXT: ret i32 [[LOAD_SROA_SPECULATED]] 30; 31bb: 32 %a = alloca %pair, align 4 33 %b = alloca %pair, align 4 34 %gep_a = getelementptr %pair, %pair* %a, i32 0, i32 1 35 %gep_b = getelementptr %pair, %pair* %b, i32 0, i32 1 36 store i32 1, i32* %gep_a, align 4 37 store i32 2, i32* %gep_b, align 4 38 %select = select i1 %cond, %pair* %a, %pair* %b 39 %gep = getelementptr %pair, %pair* %select, i32 0, i32 1 40 %load = load i32, i32* %gep, align 4 41 ret i32 %load 42} 43 44define i32 @test_sroa_select_gep_volatile_load(i1 %cond) { 45; CHECK-LABEL: @test_sroa_select_gep_volatile_load( 46; CHECK-NEXT: bb: 47; CHECK-NEXT: [[A_SROA_0:%.*]] = alloca i32, align 4 48; CHECK-NEXT: [[A_SROA_2:%.*]] = alloca i32, align 4 49; CHECK-NEXT: [[B_SROA_0:%.*]] = alloca i32, align 4 50; CHECK-NEXT: [[B_SROA_2:%.*]] = alloca i32, align 4 51; CHECK-NEXT: store i32 11, i32* [[A_SROA_0]], align 4 52; CHECK-NEXT: store i32 12, i32* [[B_SROA_0]], align 4 53; CHECK-NEXT: store i32 21, i32* [[A_SROA_2]], align 4 54; CHECK-NEXT: store i32 22, i32* [[B_SROA_2]], align 4 55; CHECK-NEXT: [[SELECT_SROA_SEL:%.*]] = select i1 [[COND:%.*]], i32* [[A_SROA_0]], i32* [[B_SROA_0]] 56; CHECK-NEXT: [[LOAD1:%.*]] = load volatile i32, i32* [[SELECT_SROA_SEL]], align 4 57; CHECK-NEXT: [[SELECT_SROA_SEL3:%.*]] = select i1 [[COND]], i32* [[A_SROA_2]], i32* [[B_SROA_2]] 58; CHECK-NEXT: [[LOAD2:%.*]] = load volatile i32, i32* [[SELECT_SROA_SEL3]], align 4 59; CHECK-NEXT: [[ADD:%.*]] = add i32 [[LOAD1]], [[LOAD2]] 60; CHECK-NEXT: ret i32 [[ADD]] 61; 62bb: 63 %a = alloca %pair, align 4 64 %b = alloca %pair, align 4 65 %gep_a0 = getelementptr inbounds %pair, %pair* %a, i32 0, i32 0 66 %gep_b0 = getelementptr inbounds %pair, %pair* %b, i32 0, i32 0 67 store i32 11, i32* %gep_a0, align 4 68 store i32 12, i32* %gep_b0, align 4 69 %gep_a1 = getelementptr inbounds %pair, %pair* %a, i32 0, i32 1 70 %gep_b1 = getelementptr inbounds %pair, %pair* %b, i32 0, i32 1 71 store i32 21, i32* %gep_a1, align 4 72 store i32 22, i32* %gep_b1, align 4 73 %select = select i1 %cond, %pair* %a, %pair* %b 74 %gep1 = getelementptr inbounds %pair, %pair* %select, i32 0, i32 0 75 %load1 = load volatile i32, i32* %gep1, align 4 76 %gep2 = getelementptr inbounds %pair, %pair* %select, i32 0, i32 1 77 %load2 = load volatile i32, i32* %gep2, align 4 78 %add = add i32 %load1, %load2 79 ret i32 %add 80} 81 82define i32 @test_sroa_select_gep_undef(i1 %cond) { 83; CHECK-LABEL: @test_sroa_select_gep_undef( 84; CHECK-NEXT: bb: 85; CHECK-NEXT: [[A_SROA_0:%.*]] = alloca i32, align 4 86; CHECK-NEXT: [[SELECT_SROA_SEL:%.*]] = select i1 [[COND:%.*]], i32* [[A_SROA_0]], i32* poison 87; CHECK-NEXT: [[LOAD:%.*]] = load i32, i32* [[SELECT_SROA_SEL]], align 4 88; CHECK-NEXT: ret i32 [[LOAD]] 89; 90bb: 91 %a = alloca %pair, align 4 92 %select = select i1 %cond, %pair* %a, %pair* undef 93 %gep = getelementptr inbounds %pair, %pair* %select, i32 0, i32 1 94 %load = load i32, i32* %gep, align 4 95 ret i32 %load 96} 97 98define i32 @test_sroa_gep_select_gep(i1 %cond) { 99; CHECK-LABEL: @test_sroa_gep_select_gep( 100; CHECK-NEXT: bb: 101; CHECK-NEXT: [[A_SROA_0:%.*]] = alloca i32, align 4 102; CHECK-NEXT: [[B_SROA_0:%.*]] = alloca i32, align 4 103; CHECK-NEXT: store i32 1, i32* [[A_SROA_0]], align 4 104; CHECK-NEXT: store i32 2, i32* [[B_SROA_0]], align 4 105; CHECK-NEXT: [[SELECT_SROA_SEL:%.*]] = select i1 [[COND:%.*]], i32* [[A_SROA_0]], i32* [[B_SROA_0]] 106; CHECK-NEXT: [[SELECT2:%.*]] = select i1 [[COND]], i32* [[SELECT_SROA_SEL]], i32* [[A_SROA_0]] 107; CHECK-NEXT: [[LOAD:%.*]] = load i32, i32* [[SELECT2]], align 4 108; CHECK-NEXT: ret i32 [[LOAD]] 109; 110bb: 111 %a = alloca %pair, align 4 112 %b = alloca %pair, align 4 113 %gep_a = getelementptr inbounds %pair, %pair* %a, i32 0, i32 1 114 %gep_b = getelementptr inbounds %pair, %pair* %b, i32 0, i32 1 115 store i32 1, i32* %gep_a, align 4 116 store i32 2, i32* %gep_b, align 4 117 %select = select i1 %cond, i32* %gep_a, i32* %gep_b 118 %gep = getelementptr inbounds i32, i32* %select, i32 0 119 %select2 = select i1 %cond, i32* %gep, i32* %gep_a 120 %load = load i32, i32* %select2, align 4 121 ret i32 %load 122} 123 124define i32 @test_sroa_gep_select_gep_nonconst_idx(i1 %cond, i32 %idx) { 125; CHECK-LABEL: @test_sroa_gep_select_gep_nonconst_idx( 126; CHECK-NEXT: bb: 127; CHECK-NEXT: [[A:%.*]] = alloca [[PAIR:%.*]], align 4 128; CHECK-NEXT: [[B:%.*]] = alloca [[PAIR]], align 4 129; CHECK-NEXT: [[GEP_A:%.*]] = getelementptr inbounds [[PAIR]], %pair* [[A]], i32 0, i32 1 130; CHECK-NEXT: [[GEP_B:%.*]] = getelementptr inbounds [[PAIR]], %pair* [[B]], i32 0, i32 1 131; CHECK-NEXT: store i32 1, i32* [[GEP_A]], align 4 132; CHECK-NEXT: store i32 2, i32* [[GEP_B]], align 4 133; CHECK-NEXT: [[SELECT:%.*]] = select i1 [[COND:%.*]], %pair* [[A]], %pair* [[B]] 134; CHECK-NEXT: [[GEP:%.*]] = getelementptr inbounds [[PAIR]], %pair* [[SELECT]], i32 [[IDX:%.*]], i32 1 135; CHECK-NEXT: [[LOAD:%.*]] = load i32, i32* [[GEP]], align 4 136; CHECK-NEXT: ret i32 [[LOAD]] 137; 138bb: 139 %a = alloca %pair, align 4 140 %b = alloca %pair, align 4 141 %gep_a = getelementptr inbounds %pair, %pair* %a, i32 0, i32 1 142 %gep_b = getelementptr inbounds %pair, %pair* %b, i32 0, i32 1 143 store i32 1, i32* %gep_a, align 4 144 store i32 2, i32* %gep_b, align 4 145 %select = select i1 %cond, %pair* %a, %pair* %b 146 %gep = getelementptr inbounds %pair, %pair* %select, i32 %idx, i32 1 147 %load = load i32, i32* %gep, align 4 148 ret i32 %load 149} 150