1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py 2; Verify that calls to atoi and related conversion functions with members 3; of constant structs as arguments are folded to constants as expected. 4; RUN: opt < %s -passes=instcombine -S | FileCheck %s 5 6declare i32 @atoi(i8*) 7declare i64 @atol(i8*) 8declare i64 @atoll(i8*) 9 10declare i64 @strtol(i8*, i8**, i32) 11declare i64 @strtoll(i8*, i8**, i32) 12 13%struct.A = type { [4 x i8], [5 x i8], [7 x i8] } 14 15@a = constant [2 x %struct.A] [%struct.A { [4 x i8] c"1\00\00\00", [5 x i8] c"12\00\00\00", [7 x i8] c"56789\00\00" }, %struct.A { [4 x i8] c"123\00", [5 x i8] c"1234\00", [7 x i8] c"67890\00\00" }] 16 17 18; Fold atoi(a[I].M) for constant I in [0, 1] and member M in [a, b] 19; to a constant. 20 21define void @fold_atoi_member(i32* %pi) { 22; CHECK-LABEL: @fold_atoi_member( 23; CHECK-NEXT: [[IA0A:%.*]] = call i32 @atoi(i8* getelementptr inbounds ([2 x %struct.A], [2 x %struct.A]* @a, i64 0, i64 0, i32 0, i64 0)) 24; CHECK-NEXT: store i32 [[IA0A]], i32* [[PI:%.*]], align 4 25; CHECK-NEXT: [[IA0B:%.*]] = call i32 @atoi(i8* getelementptr inbounds ([2 x %struct.A], [2 x %struct.A]* @a, i64 0, i64 0, i32 1, i64 0)) 26; CHECK-NEXT: [[PIA0B:%.*]] = getelementptr i32, i32* [[PI]], i64 1 27; CHECK-NEXT: store i32 [[IA0B]], i32* [[PIA0B]], align 4 28; CHECK-NEXT: [[IA1A:%.*]] = call i32 @atoi(i8* getelementptr inbounds ([2 x %struct.A], [2 x %struct.A]* @a, i64 0, i64 1, i32 0, i64 0)) 29; CHECK-NEXT: [[PIA1A:%.*]] = getelementptr i32, i32* [[PI]], i64 2 30; CHECK-NEXT: store i32 [[IA1A]], i32* [[PIA1A]], align 4 31; CHECK-NEXT: [[IA1B:%.*]] = call i32 @atoi(i8* getelementptr inbounds ([2 x %struct.A], [2 x %struct.A]* @a, i64 0, i64 1, i32 1, i64 0)) 32; CHECK-NEXT: [[PIA1B:%.*]] = getelementptr i32, i32* [[PI]], i64 3 33; CHECK-NEXT: store i32 [[IA1B]], i32* [[PIA1B]], align 4 34; CHECK-NEXT: ret void 35; 36; Fold atoi(a[0].a) to 1. 37 %pa0a = getelementptr [2 x %struct.A], [2 x %struct.A]* @a, i64 0, i64 0, i32 0, i64 0 38 %ia0a = call i32 @atoi(i8* %pa0a) 39 %pia0a = getelementptr i32, i32* %pi, i32 0 40 store i32 %ia0a, i32* %pia0a 41 42; Fold atoi(a[0].b) to 12. 43 %pa0b = getelementptr [2 x %struct.A], [2 x %struct.A]* @a, i64 0, i64 0, i32 1, i64 0 44 %ia0b = call i32 @atoi(i8* %pa0b) 45 %pia0b = getelementptr i32, i32* %pi, i32 1 46 store i32 %ia0b, i32* %pia0b 47 48; Fold atoi(a[1].a) to 123. 49 %pa1a = getelementptr [2 x %struct.A], [2 x %struct.A]* @a, i64 0, i64 1, i32 0, i64 0 50 %ia1a = call i32 @atoi(i8* %pa1a) 51 %pia1a = getelementptr i32, i32* %pi, i32 2 52 store i32 %ia1a, i32* %pia1a 53 54; Fold atoi(a[1].b) to 1234. 55 %pa1b = getelementptr [2 x %struct.A], [2 x %struct.A]* @a, i64 0, i64 1, i32 1, i64 0 56 %ia1b = call i32 @atoi(i8* %pa1b) 57 %pia1b = getelementptr i32, i32* %pi, i32 3 58 store i32 %ia1b, i32* %pia1b 59 60 ret void 61} 62 63 64; Do not fold atoi with an excessive offset. It's undefined so folding 65; it (e.g., to zero) would be valid and might prevent crashes or returning 66; a bogus value but could also prevent detecting the bug by sanitizers. 67 68define void @call_atoi_offset_out_of_bounds(i32* %pi) { 69; CHECK-LABEL: @call_atoi_offset_out_of_bounds( 70; CHECK-NEXT: [[IA_0_0_32:%.*]] = call i32 @atoi(i8* getelementptr inbounds ([2 x %struct.A], [2 x %struct.A]* @a, i64 1, i64 0, i32 0, i64 0)) 71; CHECK-NEXT: store i32 [[IA_0_0_32]], i32* [[PI:%.*]], align 4 72; CHECK-NEXT: [[IA_0_0_33:%.*]] = call i32 @atoi(i8* getelementptr ([2 x %struct.A], [2 x %struct.A]* @a, i64 1, i64 0, i32 0, i64 1)) 73; CHECK-NEXT: store i32 [[IA_0_0_33]], i32* [[PI]], align 4 74; CHECK-NEXT: ret void 75; 76; Do not fold atoi((const char*)a + sizeof a). 77 %pa_0_0_32 = getelementptr [2 x %struct.A], [2 x %struct.A]* @a, i64 0, i64 0, i32 0, i64 32 78 %ia_0_0_32 = call i32 @atoi(i8* %pa_0_0_32) 79 %pia_0_0_32 = getelementptr i32, i32* %pi, i32 0 80 store i32 %ia_0_0_32, i32* %pia_0_0_32 81 82; Likewise, do not fold atoi((const char*)a + sizeof a + 1). 83 %pa_0_0_33 = getelementptr [2 x %struct.A], [2 x %struct.A]* @a, i64 0, i64 0, i32 0, i64 33 84 %ia_0_0_33 = call i32 @atoi(i8* %pa_0_0_33) 85 %pia_0_0_33 = getelementptr i32, i32* %pi, i32 0 86 store i32 %ia_0_0_33, i32* %pia_0_0_33 87 88 ret void 89} 90 91 92; Fold atol(a[I].M) for constant I in [0, 1] and member M in [a, b, c] 93; to a constant. 94 95define void @fold_atol_member(i64* %pi) { 96; CHECK-LABEL: @fold_atol_member( 97; CHECK-NEXT: [[IA0A:%.*]] = call i64 @atol(i8* getelementptr inbounds ([2 x %struct.A], [2 x %struct.A]* @a, i64 0, i64 0, i32 0, i64 0)) 98; CHECK-NEXT: store i64 [[IA0A]], i64* [[PI:%.*]], align 4 99; CHECK-NEXT: [[IA0B:%.*]] = call i64 @atol(i8* getelementptr inbounds ([2 x %struct.A], [2 x %struct.A]* @a, i64 0, i64 0, i32 1, i64 0)) 100; CHECK-NEXT: [[PIA0B:%.*]] = getelementptr i64, i64* [[PI]], i64 1 101; CHECK-NEXT: store i64 [[IA0B]], i64* [[PIA0B]], align 4 102; CHECK-NEXT: [[IA0C:%.*]] = call i64 @atol(i8* getelementptr inbounds ([2 x %struct.A], [2 x %struct.A]* @a, i64 0, i64 0, i32 2, i64 0)) 103; CHECK-NEXT: [[PIA0C:%.*]] = getelementptr i64, i64* [[PI]], i64 2 104; CHECK-NEXT: store i64 [[IA0C]], i64* [[PIA0C]], align 4 105; CHECK-NEXT: [[IA1A:%.*]] = call i64 @atol(i8* getelementptr inbounds ([2 x %struct.A], [2 x %struct.A]* @a, i64 0, i64 1, i32 0, i64 0)) 106; CHECK-NEXT: [[PIA1A:%.*]] = getelementptr i64, i64* [[PI]], i64 3 107; CHECK-NEXT: store i64 [[IA1A]], i64* [[PIA1A]], align 4 108; CHECK-NEXT: [[IA1B:%.*]] = call i64 @atol(i8* getelementptr inbounds ([2 x %struct.A], [2 x %struct.A]* @a, i64 0, i64 1, i32 1, i64 0)) 109; CHECK-NEXT: [[PIA1B:%.*]] = getelementptr i64, i64* [[PI]], i64 4 110; CHECK-NEXT: store i64 [[IA1B]], i64* [[PIA1B]], align 4 111; CHECK-NEXT: [[IA1C:%.*]] = call i64 @atol(i8* getelementptr inbounds ([2 x %struct.A], [2 x %struct.A]* @a, i64 0, i64 1, i32 2, i64 0)) 112; CHECK-NEXT: [[PIA1C:%.*]] = getelementptr i64, i64* [[PI]], i64 5 113; CHECK-NEXT: store i64 [[IA1C]], i64* [[PIA1C]], align 4 114; CHECK-NEXT: ret void 115; 116; Fold atol(a[0].a) to 1. 117 %pa0a = getelementptr [2 x %struct.A], [2 x %struct.A]* @a, i64 0, i64 0, i32 0, i64 0 118 %ia0a = call i64 @atol(i8* %pa0a) 119 %pia0a = getelementptr i64, i64* %pi, i32 0 120 store i64 %ia0a, i64* %pia0a 121 122; Fold atol(a[0].b) to 12. 123 %pa0b = getelementptr [2 x %struct.A], [2 x %struct.A]* @a, i64 0, i64 0, i32 1, i64 0 124 %ia0b = call i64 @atol(i8* %pa0b) 125 %pia0b = getelementptr i64, i64* %pi, i32 1 126 store i64 %ia0b, i64* %pia0b 127 128; Fold atol(a[0].c) to 56789. 129 %pa0c = getelementptr [2 x %struct.A], [2 x %struct.A]* @a, i64 0, i64 0, i32 2, i64 0 130 %ia0c = call i64 @atol(i8* %pa0c) 131 %pia0c = getelementptr i64, i64* %pi, i32 2 132 store i64 %ia0c, i64* %pia0c 133 134; Fold atol(a[1].a) to 123. 135 %pa1a = getelementptr [2 x %struct.A], [2 x %struct.A]* @a, i64 0, i64 1, i32 0, i64 0 136 %ia1a = call i64 @atol(i8* %pa1a) 137 %pia1a = getelementptr i64, i64* %pi, i32 3 138 store i64 %ia1a, i64* %pia1a 139 140; Fold atol(a[1].b) to 1234. 141 %pa1b = getelementptr [2 x %struct.A], [2 x %struct.A]* @a, i64 0, i64 1, i32 1, i64 0 142 %ia1b = call i64 @atol(i8* %pa1b) 143 %pia1b = getelementptr i64, i64* %pi, i32 4 144 store i64 %ia1b, i64* %pia1b 145 146; Fold atol(a[1].c) to 67890. 147 %pa1c = getelementptr [2 x %struct.A], [2 x %struct.A]* @a, i64 0, i64 1, i32 2, i64 0 148 %ia1c = call i64 @atol(i8* %pa1c) 149 %pia1c = getelementptr i64, i64* %pi, i32 5 150 store i64 %ia1c, i64* %pia1c 151 152 ret void 153} 154 155 156; Fold atoll(a[I].M + C) for constant I in [0, 1], member M in [a, b, c], 157; and C in a valid range to a constant. 158 159define void @fold_atoll_member_pC(i64* %pi) { 160; CHECK-LABEL: @fold_atoll_member_pC( 161; CHECK-NEXT: [[IA0A:%.*]] = call i64 @atol(i8* getelementptr inbounds ([2 x %struct.A], [2 x %struct.A]* @a, i64 0, i64 0, i32 0, i64 0)) 162; CHECK-NEXT: store i64 [[IA0A]], i64* [[PI:%.*]], align 4 163; CHECK-NEXT: [[IA0BP1:%.*]] = call i64 @atol(i8* getelementptr inbounds ([2 x %struct.A], [2 x %struct.A]* @a, i64 0, i64 0, i32 1, i64 1)) 164; CHECK-NEXT: [[PIA0BP1:%.*]] = getelementptr i64, i64* [[PI]], i64 1 165; CHECK-NEXT: store i64 [[IA0BP1]], i64* [[PIA0BP1]], align 4 166; CHECK-NEXT: [[IA0CP3:%.*]] = call i64 @atol(i8* getelementptr inbounds ([2 x %struct.A], [2 x %struct.A]* @a, i64 0, i64 0, i32 2, i64 3)) 167; CHECK-NEXT: [[PIA0CP3:%.*]] = getelementptr i64, i64* [[PI]], i64 2 168; CHECK-NEXT: store i64 [[IA0CP3]], i64* [[PIA0CP3]], align 4 169; CHECK-NEXT: [[IA1AP2:%.*]] = call i64 @atol(i8* getelementptr inbounds ([2 x %struct.A], [2 x %struct.A]* @a, i64 0, i64 1, i32 0, i64 2)) 170; CHECK-NEXT: [[PIA1AP2:%.*]] = getelementptr i64, i64* [[PI]], i64 3 171; CHECK-NEXT: store i64 [[IA1AP2]], i64* [[PIA1AP2]], align 4 172; CHECK-NEXT: [[IA1BP3:%.*]] = call i64 @atol(i8* getelementptr inbounds ([2 x %struct.A], [2 x %struct.A]* @a, i64 0, i64 1, i32 1, i64 3)) 173; CHECK-NEXT: [[PIA1BP3:%.*]] = getelementptr i64, i64* [[PI]], i64 4 174; CHECK-NEXT: store i64 [[IA1BP3]], i64* [[PIA1BP3]], align 4 175; CHECK-NEXT: [[IA1CP4:%.*]] = call i64 @atol(i8* getelementptr inbounds ([2 x %struct.A], [2 x %struct.A]* @a, i64 0, i64 1, i32 2, i64 4)) 176; CHECK-NEXT: [[PIA1CP4:%.*]] = getelementptr i64, i64* [[PI]], i64 5 177; CHECK-NEXT: store i64 [[IA1CP4]], i64* [[PIA1CP4]], align 4 178; CHECK-NEXT: ret void 179; 180; Fold atoll(a[0].a) to 1. 181 %pa0a = getelementptr [2 x %struct.A], [2 x %struct.A]* @a, i64 0, i64 0, i32 0, i64 0 182 %ia0a = call i64 @atol(i8* %pa0a) 183 %pia0a = getelementptr i64, i64* %pi, i32 0 184 store i64 %ia0a, i64* %pia0a 185 186; Fold atoll(a[0].b + 1) to 2. 187 %pa0bp1 = getelementptr [2 x %struct.A], [2 x %struct.A]* @a, i64 0, i64 0, i32 1, i64 1 188 %ia0bp1 = call i64 @atol(i8* %pa0bp1) 189 %pia0bp1 = getelementptr i64, i64* %pi, i32 1 190 store i64 %ia0bp1, i64* %pia0bp1 191 192; Fold atoll(a[0].c + 3) to 89. 193 %pa0cp3 = getelementptr [2 x %struct.A], [2 x %struct.A]* @a, i64 0, i64 0, i32 2, i64 3 194 %ia0cp3 = call i64 @atol(i8* %pa0cp3) 195 %pia0cp3 = getelementptr i64, i64* %pi, i32 2 196 store i64 %ia0cp3, i64* %pia0cp3 197 198; Fold atoll(a[1].a + 2) to 3. 199 %pa1ap2 = getelementptr [2 x %struct.A], [2 x %struct.A]* @a, i64 0, i64 1, i32 0, i64 2 200 %ia1ap2 = call i64 @atol(i8* %pa1ap2) 201 %pia1ap2 = getelementptr i64, i64* %pi, i32 3 202 store i64 %ia1ap2, i64* %pia1ap2 203 204; Fold atoll(a[1].b + 3) to 4. 205 %pa1bp3 = getelementptr [2 x %struct.A], [2 x %struct.A]* @a, i64 0, i64 1, i32 1, i64 3 206 %ia1bp3 = call i64 @atol(i8* %pa1bp3) 207 %pia1bp3 = getelementptr i64, i64* %pi, i32 4 208 store i64 %ia1bp3, i64* %pia1bp3 209 210; Fold atoll(a[1].c + 4) to 0. 211 %pa1cp4 = getelementptr [2 x %struct.A], [2 x %struct.A]* @a, i64 0, i64 1, i32 2, i64 4 212 %ia1cp4 = call i64 @atol(i8* %pa1cp4) 213 %pia1cp4 = getelementptr i64, i64* %pi, i32 5 214 store i64 %ia1cp4, i64* %pia1cp4 215 216 ret void 217} 218 219 220; Fold strtol(a[I].M + C, 0, 0) for constant I in [0, 1], member M in [a, b, c], 221; and C in a valid range to a constant. 222 223define void @fold_strtol_member_pC(i64* %pi) { 224; CHECK-LABEL: @fold_strtol_member_pC( 225; CHECK-NEXT: [[IA0A:%.*]] = call i64 @strtol(i8* nocapture getelementptr inbounds ([2 x %struct.A], [2 x %struct.A]* @a, i64 0, i64 0, i32 0, i64 0), i8** null, i32 0) 226; CHECK-NEXT: store i64 [[IA0A]], i64* [[PI:%.*]], align 4 227; CHECK-NEXT: [[IA0BP1:%.*]] = call i64 @strtol(i8* nocapture getelementptr inbounds ([2 x %struct.A], [2 x %struct.A]* @a, i64 0, i64 0, i32 1, i64 1), i8** null, i32 0) 228; CHECK-NEXT: [[PIA0BP1:%.*]] = getelementptr i64, i64* [[PI]], i64 1 229; CHECK-NEXT: store i64 [[IA0BP1]], i64* [[PIA0BP1]], align 4 230; CHECK-NEXT: [[IA0CP3:%.*]] = call i64 @strtol(i8* nocapture getelementptr inbounds ([2 x %struct.A], [2 x %struct.A]* @a, i64 0, i64 0, i32 2, i64 3), i8** null, i32 0) 231; CHECK-NEXT: [[PIA0CP3:%.*]] = getelementptr i64, i64* [[PI]], i64 2 232; CHECK-NEXT: store i64 [[IA0CP3]], i64* [[PIA0CP3]], align 4 233; CHECK-NEXT: [[IA1AP2:%.*]] = call i64 @strtol(i8* nocapture getelementptr inbounds ([2 x %struct.A], [2 x %struct.A]* @a, i64 0, i64 1, i32 0, i64 2), i8** null, i32 0) 234; CHECK-NEXT: [[PIA1AP2:%.*]] = getelementptr i64, i64* [[PI]], i64 3 235; CHECK-NEXT: store i64 [[IA1AP2]], i64* [[PIA1AP2]], align 4 236; CHECK-NEXT: [[IA1BP3:%.*]] = call i64 @strtol(i8* nocapture getelementptr inbounds ([2 x %struct.A], [2 x %struct.A]* @a, i64 0, i64 1, i32 1, i64 3), i8** null, i32 0) 237; CHECK-NEXT: [[PIA1BP3:%.*]] = getelementptr i64, i64* [[PI]], i64 4 238; CHECK-NEXT: store i64 [[IA1BP3]], i64* [[PIA1BP3]], align 4 239; CHECK-NEXT: [[IA1CP4:%.*]] = call i64 @strtol(i8* nocapture getelementptr inbounds ([2 x %struct.A], [2 x %struct.A]* @a, i64 0, i64 1, i32 2, i64 4), i8** null, i32 0) 240; CHECK-NEXT: [[PIA1CP4:%.*]] = getelementptr i64, i64* [[PI]], i64 5 241; CHECK-NEXT: store i64 [[IA1CP4]], i64* [[PIA1CP4]], align 4 242; CHECK-NEXT: ret void 243; 244; Fold strtol(a[0].a, 0, 0) to 1. 245 %pa0a = getelementptr [2 x %struct.A], [2 x %struct.A]* @a, i64 0, i64 0, i32 0, i64 0 246 %ia0a = call i64 @strtol(i8* %pa0a, i8** null, i32 0) 247 %pia0a = getelementptr i64, i64* %pi, i32 0 248 store i64 %ia0a, i64* %pia0a 249 250; Fold strtol(a[0].b + 1, 0, 0, i8** null, i32 0) to 2. 251 %pa0bp1 = getelementptr [2 x %struct.A], [2 x %struct.A]* @a, i64 0, i64 0, i32 1, i64 1 252 %ia0bp1 = call i64 @strtol(i8* %pa0bp1, i8** null, i32 0) 253 %pia0bp1 = getelementptr i64, i64* %pi, i32 1 254 store i64 %ia0bp1, i64* %pia0bp1 255 256; Fold strtol(a[0].c + 3, 0, 0, i8** null, i32 0) to 89. 257 %pa0cp3 = getelementptr [2 x %struct.A], [2 x %struct.A]* @a, i64 0, i64 0, i32 2, i64 3 258 %ia0cp3 = call i64 @strtol(i8* %pa0cp3, i8** null, i32 0) 259 %pia0cp3 = getelementptr i64, i64* %pi, i32 2 260 store i64 %ia0cp3, i64* %pia0cp3 261 262; Fold strtol(a[1].a + 2, 0, 0, i8** null, i32 0) to 3. 263 %pa1ap2 = getelementptr [2 x %struct.A], [2 x %struct.A]* @a, i64 0, i64 1, i32 0, i64 2 264 %ia1ap2 = call i64 @strtol(i8* %pa1ap2, i8** null, i32 0) 265 %pia1ap2 = getelementptr i64, i64* %pi, i32 3 266 store i64 %ia1ap2, i64* %pia1ap2 267 268; Fold strtol(a[1].b + 3, 0, 0, i8** null, i32 0) to 4. 269 %pa1bp3 = getelementptr [2 x %struct.A], [2 x %struct.A]* @a, i64 0, i64 1, i32 1, i64 3 270 %ia1bp3 = call i64 @strtol(i8* %pa1bp3, i8** null, i32 0) 271 %pia1bp3 = getelementptr i64, i64* %pi, i32 4 272 store i64 %ia1bp3, i64* %pia1bp3 273 274; Fold strtol(a[1].c + 4, 0, 0, i8** null, i32 0) to 0. 275 %pa1cp4 = getelementptr [2 x %struct.A], [2 x %struct.A]* @a, i64 0, i64 1, i32 2, i64 4 276 %ia1cp4 = call i64 @strtol(i8* %pa1cp4, i8** null, i32 0) 277 %pia1cp4 = getelementptr i64, i64* %pi, i32 5 278 store i64 %ia1cp4, i64* %pia1cp4 279 280 ret void 281} 282 283 284; Fold strtoll(a[I].M + C, 0, 0) for constant I in [0, 1], member M 285; in [a, b, c], and C in a valid range to a constant. 286 287define void @fold_strtoll_member_pC(i64* %pi) { 288; CHECK-LABEL: @fold_strtoll_member_pC( 289; CHECK-NEXT: [[IA0A:%.*]] = call i64 @strtoll(i8* nocapture getelementptr inbounds ([2 x %struct.A], [2 x %struct.A]* @a, i64 0, i64 0, i32 0, i64 0), i8** null, i32 0) 290; CHECK-NEXT: store i64 [[IA0A]], i64* [[PI:%.*]], align 4 291; CHECK-NEXT: [[IA0BP1:%.*]] = call i64 @strtoll(i8* nocapture getelementptr inbounds ([2 x %struct.A], [2 x %struct.A]* @a, i64 0, i64 0, i32 1, i64 1), i8** null, i32 0) 292; CHECK-NEXT: [[PIA0BP1:%.*]] = getelementptr i64, i64* [[PI]], i64 1 293; CHECK-NEXT: store i64 [[IA0BP1]], i64* [[PIA0BP1]], align 4 294; CHECK-NEXT: [[IA0CP3:%.*]] = call i64 @strtoll(i8* nocapture getelementptr inbounds ([2 x %struct.A], [2 x %struct.A]* @a, i64 0, i64 0, i32 2, i64 3), i8** null, i32 0) 295; CHECK-NEXT: [[PIA0CP3:%.*]] = getelementptr i64, i64* [[PI]], i64 2 296; CHECK-NEXT: store i64 [[IA0CP3]], i64* [[PIA0CP3]], align 4 297; CHECK-NEXT: [[IA1AP2:%.*]] = call i64 @strtoll(i8* nocapture getelementptr inbounds ([2 x %struct.A], [2 x %struct.A]* @a, i64 0, i64 1, i32 0, i64 2), i8** null, i32 0) 298; CHECK-NEXT: [[PIA1AP2:%.*]] = getelementptr i64, i64* [[PI]], i64 3 299; CHECK-NEXT: store i64 [[IA1AP2]], i64* [[PIA1AP2]], align 4 300; CHECK-NEXT: [[IA1BP3:%.*]] = call i64 @strtoll(i8* nocapture getelementptr inbounds ([2 x %struct.A], [2 x %struct.A]* @a, i64 0, i64 1, i32 1, i64 3), i8** null, i32 0) 301; CHECK-NEXT: [[PIA1BP3:%.*]] = getelementptr i64, i64* [[PI]], i64 4 302; CHECK-NEXT: store i64 [[IA1BP3]], i64* [[PIA1BP3]], align 4 303; CHECK-NEXT: [[IA1CP4:%.*]] = call i64 @strtoll(i8* nocapture getelementptr inbounds ([2 x %struct.A], [2 x %struct.A]* @a, i64 0, i64 1, i32 2, i64 4), i8** null, i32 0) 304; CHECK-NEXT: [[PIA1CP4:%.*]] = getelementptr i64, i64* [[PI]], i64 5 305; CHECK-NEXT: store i64 [[IA1CP4]], i64* [[PIA1CP4]], align 4 306; CHECK-NEXT: ret void 307; 308; Fold strtoll(a[0].a, 0, 0) to 1. 309 %pa0a = getelementptr [2 x %struct.A], [2 x %struct.A]* @a, i64 0, i64 0, i32 0, i64 0 310 %ia0a = call i64 @strtoll(i8* %pa0a, i8** null, i32 0) 311 %pia0a = getelementptr i64, i64* %pi, i32 0 312 store i64 %ia0a, i64* %pia0a 313 314; Fold strtoll(a[0].b + 1, 0, 0, i8** null, i32 0) to 2. 315 %pa0bp1 = getelementptr [2 x %struct.A], [2 x %struct.A]* @a, i64 0, i64 0, i32 1, i64 1 316 %ia0bp1 = call i64 @strtoll(i8* %pa0bp1, i8** null, i32 0) 317 %pia0bp1 = getelementptr i64, i64* %pi, i32 1 318 store i64 %ia0bp1, i64* %pia0bp1 319 320; Fold strtoll(a[0].c + 3, 0, 0, i8** null, i32 0) to 89. 321 %pa0cp3 = getelementptr [2 x %struct.A], [2 x %struct.A]* @a, i64 0, i64 0, i32 2, i64 3 322 %ia0cp3 = call i64 @strtoll(i8* %pa0cp3, i8** null, i32 0) 323 %pia0cp3 = getelementptr i64, i64* %pi, i32 2 324 store i64 %ia0cp3, i64* %pia0cp3 325 326; Fold strtoll(a[1].a + 2, 0, 0, i8** null, i32 0) to 3. 327 %pa1ap2 = getelementptr [2 x %struct.A], [2 x %struct.A]* @a, i64 0, i64 1, i32 0, i64 2 328 %ia1ap2 = call i64 @strtoll(i8* %pa1ap2, i8** null, i32 0) 329 %pia1ap2 = getelementptr i64, i64* %pi, i32 3 330 store i64 %ia1ap2, i64* %pia1ap2 331 332; Fold strtoll(a[1].b + 3, 0, 0, i8** null, i32 0) to 4. 333 %pa1bp3 = getelementptr [2 x %struct.A], [2 x %struct.A]* @a, i64 0, i64 1, i32 1, i64 3 334 %ia1bp3 = call i64 @strtoll(i8* %pa1bp3, i8** null, i32 0) 335 %pia1bp3 = getelementptr i64, i64* %pi, i32 4 336 store i64 %ia1bp3, i64* %pia1bp3 337 338; Fold strtoll(a[1].c + 4, 0, 0, i8** null, i32 0) to 0. 339 %pa1cp4 = getelementptr [2 x %struct.A], [2 x %struct.A]* @a, i64 0, i64 1, i32 2, i64 4 340 %ia1cp4 = call i64 @strtoll(i8* %pa1cp4, i8** null, i32 0) 341 %pia1cp4 = getelementptr i64, i64* %pi, i32 5 342 store i64 %ia1cp4, i64* %pia1cp4 343 344 ret void 345} 346