1 // RUN: %clang_cc1 -triple x86_64-linux-gnu -ffine-grained-bitfield-accesses \
2 // RUN: -emit-llvm -o - %s | FileCheck %s
3 // RUN: %clang_cc1 -triple x86_64-linux-gnu -ffine-grained-bitfield-accesses \
4 // RUN: -emit-llvm -fsanitize=address -o - %s | FileCheck %s --check-prefix=SANITIZE
5 // Check -fsplit-bitfields will be ignored since sanitizer is enabled.
17 // CHECK-LABEL: @_Z7read8_1v
18 // CHECK: %bf.load = load i8, ptr getelementptr inbounds (%struct.S1, ptr @a1, i32 0, i32 1), align 1
19 // CHECK-NEXT: %bf.cast = zext i8 %bf.load to i32
20 // CHECK-NEXT: ret i32 %bf.cast
21 // SANITIZE-LABEL: @_Z7read8_1v
22 // SANITIZE: %bf.load = load i32, ptr {{.*}}, align 4
23 // SANITIZE: %bf.lshr = lshr i32 %bf.load, 8
24 // SANITIZE: %bf.clear = and i32 %bf.lshr, 255
25 // SANITIZE: ret i32 %bf.clear
29 // CHECK-LABEL: @_Z8write8_1v
30 // CHECK: store i8 3, ptr getelementptr inbounds (%struct.S1, ptr @a1, i32 0, i32 1), align 1
31 // CHECK-NEXT: ret void
32 // SANITIZE-LABEL: @_Z8write8_1v
33 // SANITIZE: %bf.load = load i32, ptr {{.*}}, align 4
34 // SANITIZE-NEXT: %bf.clear = and i32 %bf.load, -65281
35 // SANITIZE-NEXT: %bf.set = or i32 %bf.clear, 768
36 // SANITIZE-NEXT: store i32 %bf.set, ptr {{.*}}, align 4
37 // SANITIZE-NEXT: ret void
42 // CHECK-LABEL: @_Z7read8_2v
43 // CHECK: %bf.load = load i16, ptr getelementptr inbounds (%struct.S1, ptr @a1, i32 0, i32 2), align 2
44 // CHECK-NEXT: %bf.lshr = lshr i16 %bf.load, 4
45 // CHECK-NEXT: %bf.clear = and i16 %bf.lshr, 255
46 // CHECK-NEXT: %bf.cast = zext i16 %bf.clear to i32
47 // CHECK-NEXT: ret i32 %bf.cast
48 // SANITIZE-LABEL: @_Z7read8_2v
49 // SANITIZE: %bf.load = load i32, ptr {{.*}}, align 4
50 // SANITIZE-NEXT: %bf.lshr = lshr i32 %bf.load, 20
51 // SANITIZE-NEXT: %bf.clear = and i32 %bf.lshr, 255
52 // SANITIZE-NEXT: ret i32 %bf.clear
56 // CHECK-LABEL: @_Z8write8_2v
57 // CHECK: %bf.load = load i16, ptr getelementptr inbounds (%struct.S1, ptr @a1, i32 0, i32 2), align 2
58 // CHECK-NEXT: %bf.clear = and i16 %bf.load, -4081
59 // CHECK-NEXT: %bf.set = or i16 %bf.clear, 48
60 // CHECK-NEXT: store i16 %bf.set, ptr getelementptr inbounds (%struct.S1, ptr @a1, i32 0, i32 2), align 2
61 // CHECK-NEXT: ret void
62 // SANITIZE-LABEL: @_Z8write8_2v
63 // SANITIZE: %bf.load = load i32, ptr {{.*}}, align 4
64 // SANITIZE-NEXT: %bf.clear = and i32 %bf.load, -267386881
65 // SANITIZE-NEXT: %bf.set = or i32 %bf.clear, 3145728
66 // SANITIZE-NEXT: store i32 %bf.set, ptr {{.*}}, align 4
67 // SANITIZE-NEXT: ret void
79 // CHECK-LABEL: @_Z8read16_1v
80 // CHECK: %bf.load = load i16, ptr @a2, align 8
81 // CHECK-NEXT: %bf.cast = zext i16 %bf.load to i64
82 // CHECK-NEXT: %conv = trunc i64 %bf.cast to i32
83 // CHECK-NEXT: ret i32 %conv
84 // SANITIZE-LABEL: @_Z8read16_1v
85 // SANITIZE: %bf.load = load i64, ptr {{.*}}, align 8
86 // SANITIZE-NEXT: %bf.clear = and i64 %bf.load, 65535
87 // SANITIZE-NEXT: %conv = trunc i64 %bf.clear to i32
88 // SANITIZE-NEXT: ret i32 %conv
92 // CHECK-LABEL: @_Z8read16_2v
93 // CHECK: %bf.load = load i16, ptr getelementptr inbounds (%struct.S2, ptr @a2, i32 0, i32 1), align 2
94 // CHECK-NEXT: %bf.cast = zext i16 %bf.load to i64
95 // CHECK-NEXT: %conv = trunc i64 %bf.cast to i32
96 // CHECK-NEXT: ret i32 %conv
97 // SANITIZE-LABEL: @_Z8read16_2v
98 // SANITIZE: %bf.load = load i64, ptr {{.*}}, align 8
99 // SANITIZE-NEXT: %bf.lshr = lshr i64 %bf.load, 16
100 // SANITIZE-NEXT: %bf.clear = and i64 %bf.lshr, 65535
101 // SANITIZE-NEXT: %conv = trunc i64 %bf.clear to i32
102 // SANITIZE-NEXT: ret i32 %conv
107 // CHECK-LABEL: @_Z9write16_1v
108 // CHECK: store i16 5, ptr @a2, align 8
109 // CHECK-NEXT: ret void
110 // SANITIZE-LABEL: @_Z9write16_1v
111 // SANITIZE: %bf.load = load i64, ptr {{.*}}, align 8
112 // SANITIZE-NEXT: %bf.clear = and i64 %bf.load, -65536
113 // SANITIZE-NEXT: %bf.set = or i64 %bf.clear, 5
114 // SANITIZE-NEXT: store i64 %bf.set, ptr {{.*}}, align 8
115 // SANITIZE-NEXT: ret void
119 // CHECK-LABEL: @_Z9write16_2v
120 // CHECK: store i16 5, ptr getelementptr inbounds (%struct.S2, ptr @a2, i32 0, i32 1), align 2
121 // CHECK-NEXT: ret void
122 // SANITIZE-LABEL: @_Z9write16_2v
123 // SANITIZE: %bf.load = load i64, ptr {{.*}}, align 8
124 // SANITIZE-NEXT: %bf.clear = and i64 %bf.load, -4294901761
125 // SANITIZE-NEXT: %bf.set = or i64 %bf.clear, 327680
126 // SANITIZE-NEXT: store i64 %bf.set, ptr {{.*}}, align 8
127 // SANITIZE-NEXT: ret void
138 unsigned read32_1() {
139 // CHECK-LABEL: @_Z8read32_1v
140 // CHECK: %bf.load = load i32, ptr getelementptr inbounds (%struct.S3, ptr @a3, i32 0, i32 1), align 4
141 // CHECK-NEXT: %bf.cast = zext i32 %bf.load to i64
142 // CHECK-NEXT: %conv = trunc i64 %bf.cast to i32
143 // CHECK-NEXT: ret i32 %conv
144 // SANITIZE-LABEL: @_Z8read32_1v
145 // SANITIZE: %bf.load = load i64, ptr {{.*}}, align 8
146 // SANITIZE-NEXT: %bf.lshr = lshr i64 %bf.load, 32
147 // SANITIZE-NEXT: %conv = trunc i64 %bf.lshr to i32
148 // SANITIZE-NEXT: ret i32 %conv
152 // CHECK-LABEL: @_Z9write32_1v
153 // CHECK: store i32 5, ptr getelementptr inbounds (%struct.S3, ptr @a3, i32 0, i32 1), align 4
154 // CHECK-NEXT: ret void
155 // SANITIZE-LABEL: @_Z9write32_1v
156 // SANITIZE: %bf.load = load i64, ptr {{.*}}, align 8
157 // SANITIZE-NEXT: %bf.clear = and i64 %bf.load, 4294967295
158 // SANITIZE-NEXT: %bf.set = or i64 %bf.clear, 21474836480
159 // SANITIZE-NEXT: store i64 %bf.set, ptr {{.*}}, align 8
160 // SANITIZE-NEXT: ret void