1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py 2; Verify that calls to snprintf with members of constant structs as arguments 3; are folded to constants as expected. 4; RUN: opt < %s -passes=instcombine -S | FileCheck %s 5 6declare i32 @snprintf(ptr, i64, ptr, ...) 7 8%struct.A = type { [5 x i8], [6 x i8], [7 x i8] } 9 10@a = constant [2 x %struct.A] [%struct.A { [5 x i8] c"1\00\00\00\00", [6 x i8] c"12\00\00\00\00", [7 x i8] c"123\00\00\00\00" }, %struct.A { [5 x i8] c"1234\00", [6 x i8] c"12345\00", [7 x i8] c"123456\00" }] 11 12@pcnt_s = constant [3 x i8] c"%s\00" 13 14 15; Fold snprintf(0, 0, "%s", a[I].M + C) for constant I in [0, 1], 16; member M in [a, b, c], and C in a valid range to a constant. 17 18define void @fold_snprintf_member_pC(ptr %pi) { 19; CHECK-LABEL: @fold_snprintf_member_pC( 20; CHECK-NEXT: store i32 1, ptr [[PI:%.*]], align 4 21; CHECK-NEXT: [[PIA0AP1:%.*]] = getelementptr i8, ptr [[PI]], i64 4 22; CHECK-NEXT: store i32 0, ptr [[PIA0AP1]], align 4 23; CHECK-NEXT: [[PIA0B:%.*]] = getelementptr i8, ptr [[PI]], i64 8 24; CHECK-NEXT: store i32 2, ptr [[PIA0B]], align 4 25; CHECK-NEXT: [[PIA0BP1:%.*]] = getelementptr i8, ptr [[PI]], i64 12 26; CHECK-NEXT: store i32 1, ptr [[PIA0BP1]], align 4 27; CHECK-NEXT: [[PIA0BP2:%.*]] = getelementptr i8, ptr [[PI]], i64 16 28; CHECK-NEXT: store i32 0, ptr [[PIA0BP2]], align 4 29; CHECK-NEXT: [[PIA0C:%.*]] = getelementptr i8, ptr [[PI]], i64 20 30; CHECK-NEXT: store i32 3, ptr [[PIA0C]], align 4 31; CHECK-NEXT: [[PIA1A:%.*]] = getelementptr i8, ptr [[PI]], i64 24 32; CHECK-NEXT: store i32 4, ptr [[PIA1A]], align 4 33; CHECK-NEXT: [[PIA1B:%.*]] = getelementptr i8, ptr [[PI]], i64 28 34; CHECK-NEXT: store i32 5, ptr [[PIA1B]], align 4 35; CHECK-NEXT: [[PIA1C:%.*]] = getelementptr i8, ptr [[PI]], i64 32 36; CHECK-NEXT: store i32 6, ptr [[PIA1C]], align 4 37; CHECK-NEXT: ret void 38; 39; Fold snprintf(0, 0, "%s", a[0].a) to 1. 40 %ia0a = call i32 (ptr, i64, ptr, ...) @snprintf(ptr null, i64 0, ptr @pcnt_s, ptr @a) 41 store i32 %ia0a, ptr %pi 42 43; Fold snprintf(0, 0, "%s", a[0].a) to 0. 44 %pa0ap1 = getelementptr [2 x %struct.A], ptr @a, i64 0, i64 0, i32 0, i64 1 45 %ia0ap1 = call i32 (ptr, i64, ptr, ...) @snprintf(ptr null, i64 0, ptr @pcnt_s, ptr %pa0ap1) 46 %pia0ap1 = getelementptr i32, ptr %pi, i32 1 47 store i32 %ia0ap1, ptr %pia0ap1 48 49; Fold snprintf(0, 0, "%s", a[0].b) to 2. 50 %pa0b = getelementptr [2 x %struct.A], ptr @a, i64 0, i64 0, i32 1, i64 0 51 %ia0b = call i32 (ptr, i64, ptr, ...) @snprintf(ptr null, i64 0, ptr @pcnt_s, ptr %pa0b) 52 %pia0b = getelementptr i32, ptr %pi, i32 2 53 store i32 %ia0b, ptr %pia0b 54 55; Fold snprintf(0, 0, "%s", a[0].b + 1) to 1. 56 %pa0bp1 = getelementptr [2 x %struct.A], ptr @a, i64 0, i64 0, i32 1, i64 1 57 %ia0bp1 = call i32 (ptr, i64, ptr, ...) @snprintf(ptr null, i64 0, ptr @pcnt_s, ptr %pa0bp1) 58 %pia0bp1 = getelementptr i32, ptr %pi, i32 3 59 store i32 %ia0bp1, ptr %pia0bp1 60 61; Fold snprintf(0, 0, "%s", a[0].b + 2) to 0. 62 %pa0bp2 = getelementptr [2 x %struct.A], ptr @a, i64 0, i64 0, i32 1, i64 2 63 %ia0bp2 = call i32 (ptr, i64, ptr, ...) @snprintf(ptr null, i64 0, ptr @pcnt_s, ptr %pa0bp2) 64 %pia0bp2 = getelementptr i32, ptr %pi, i32 4 65 store i32 %ia0bp2, ptr %pia0bp2 66 67; Fold snprintf(0, 0, "%s", a[0].c) to 3. 68 %pa0c = getelementptr [2 x %struct.A], ptr @a, i64 0, i64 0, i32 2, i64 0 69 %ia0c = call i32 (ptr, i64, ptr, ...) @snprintf(ptr null, i64 0, ptr @pcnt_s, ptr %pa0c) 70 %pia0c = getelementptr i32, ptr %pi, i32 5 71 store i32 %ia0c, ptr %pia0c 72 73; Fold snprintf(0, 0, "%s", a[1].a) to 4. 74 %pa1a = getelementptr [2 x %struct.A], ptr @a, i64 0, i64 1, i32 0, i64 0 75 %ia1a = call i32 (ptr, i64, ptr, ...) @snprintf(ptr null, i64 0, ptr @pcnt_s, ptr %pa1a) 76 %pia1a = getelementptr i32, ptr %pi, i32 6 77 store i32 %ia1a, ptr %pia1a 78 79; Fold snprintf(0, 0, "%s", a[1].b) to 5. 80 %pa1b = getelementptr [2 x %struct.A], ptr @a, i64 0, i64 1, i32 1, i64 0 81 %ia1b = call i32 (ptr, i64, ptr, ...) @snprintf(ptr null, i64 0, ptr @pcnt_s, ptr %pa1b) 82 %pia1b = getelementptr i32, ptr %pi, i32 7 83 store i32 %ia1b, ptr %pia1b 84 85; Fold snprintf(0, 0, "%s", a[1].c) to 6. 86 %pa1c = getelementptr [2 x %struct.A], ptr @a, i64 0, i64 1, i32 2, i64 0 87 %ia1c = call i32 (ptr, i64, ptr, ...) @snprintf(ptr null, i64 0, ptr @pcnt_s, ptr %pa1c) 88 %pia1c = getelementptr i32, ptr %pi, i32 8 89 store i32 %ia1c, ptr %pia1c 90 91 ret void 92} 93