Run DCE after a LoopFlatten test to reduce spurious output [nfc]
[llvm-project.git] / clang / test / CodeGenCXX / finegrain-bitfield-access.cpp
blob648c5263b98bbb8fd5af8871d0d3706fa92cf989
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.
7 struct S1 {
8 unsigned f1:2;
9 unsigned f2:6;
10 unsigned f3:8;
11 unsigned f4:4;
12 unsigned f5:8;
15 S1 a1;
16 unsigned read8_1() {
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
26 return a1.f3;
28 void write8_1() {
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
38 a1.f3 = 3;
41 unsigned read8_2() {
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
53 return a1.f5;
55 void write8_2() {
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
68 a1.f5 = 3;
71 struct S2 {
72 unsigned long f1:16;
73 unsigned long f2:16;
74 unsigned long f3:6;
77 S2 a2;
78 unsigned read16_1() {
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
89 return a2.f1;
91 unsigned read16_2() {
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
103 return a2.f2;
106 void write16_1() {
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
116 a2.f1 = 5;
118 void write16_2() {
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
128 a2.f2 = 5;
131 struct S3 {
132 unsigned long f1:14;
133 unsigned long f2:18;
134 unsigned long f3:32;
137 S3 a3;
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
149 return a3.f3;
151 void write32_1() {
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
161 a3.f3 = 5;