xref: /llvm-project/clang/test/CodeGenCXX/ignored-bitfield-conditional.cpp (revision cd50f910f4d1a6bb54fd8968f067febbc7320f28)
16f20744bSErich Keane // RUN: %clang_cc1 -triple x86_64-unknown-linux-gnu -emit-llvm -o - %s | FileCheck %s
26f20744bSErich Keane 
36f20744bSErich Keane struct S {
46f20744bSErich Keane   int field1 : 5;
56f20744bSErich Keane   int field2 : 6;
66f20744bSErich Keane   int field3 : 3;
76f20744bSErich Keane };
86f20744bSErich Keane 
use(bool cond,struct S s1,struct S s2,int val1,int val2)96f20744bSErich Keane void use(bool cond, struct S s1, struct S s2, int val1, int val2) {
10*cd50f910SSameer Sahasrabuddhe   // CHECK-LABEL: define {{.*}}use{{.*}}(
116f20744bSErich Keane   // CHECK: %[[S1:.+]] = alloca %struct.S
126f20744bSErich Keane   // CHECK: %[[S2:.+]] = alloca %struct.S
136f20744bSErich Keane   // CHECK: %[[COND:.+]] = alloca i8
146f20744bSErich Keane   // CHECK: %[[VAL1:.+]] = alloca i32
156f20744bSErich Keane   // CHECK: %[[VAL2:.+]] = alloca i32
166f20744bSErich Keane 
176f20744bSErich Keane   cond ? s1.field1 = val1 : s1.field2 = val2;
186f20744bSErich Keane   // Condition setup, branch.
196f20744bSErich Keane   // CHECK: %[[CONDLD:.+]] = load i8, ptr %[[COND]]
206f20744bSErich Keane   // CHECK: %[[TO_BOOL:.+]] = trunc i8 %[[CONDLD]] to i1
216f20744bSErich Keane   // CHECK: br i1 %[[TO_BOOL]], label %[[TRUE:.+]], label %[[FALSE:.+]]
226f20744bSErich Keane 
236f20744bSErich Keane   // 'True', branch set the BF, branch to 'end'.
246f20744bSErich Keane   // CHECK: [[TRUE]]:
256f20744bSErich Keane   // CHECK: %[[VAL1LD:.+]] = load i32, ptr %[[VAL1]]
266f20744bSErich Keane   // CHECK: %[[VAL1TRUNC:.+]] = trunc i32 %[[VAL1LD]] to i16
276f20744bSErich Keane   // CHECK: %[[BF_LOAD:.+]] = load i16, ptr %[[S1]]
286f20744bSErich Keane   // CHECK: %[[BF_VAL:.+]] = and i16 %[[VAL1TRUNC]], 31
296f20744bSErich Keane   // CHECK: %[[BF_CLEAR:.+]] = and i16 %[[BF_LOAD]], -32
306f20744bSErich Keane   // CHECK: %[[BF_SET:.+]] = or i16 %[[BF_CLEAR]], %[[BF_VAL]]
316f20744bSErich Keane   // CHECK: store i16 %[[BF_SET]], ptr %[[S1]]
326f20744bSErich Keane   // CHECK: br label %[[END:.+]]
336f20744bSErich Keane 
346f20744bSErich Keane   // 'False', branch set the OTHER BF, branch to 'end'.
356f20744bSErich Keane   // CHECK: [[FALSE]]:
366f20744bSErich Keane   // CHECK: %[[VAL2LD:.+]] = load i32, ptr %[[VAL2]]
376f20744bSErich Keane   // CHECK: %[[VAL2TRUNC:.+]] = trunc i32 %[[VAL2LD]] to i16
386f20744bSErich Keane   // CHECK: %[[BF_LOAD:.+]] = load i16, ptr %[[S1]]
396f20744bSErich Keane   // CHECK: %[[BF_VAL:.+]] = and i16 %[[VAL2TRUNC]], 63
406f20744bSErich Keane   // CHECK: %[[BF_SHIFT:.+]] = shl i16 %[[BF_VAL]], 5
416f20744bSErich Keane   // CHECK: %[[BF_CLEAR:.+]] = and i16 %[[BF_LOAD]], -2017
426f20744bSErich Keane   // CHECK: %[[BF_SET:.+]] = or i16 %[[BF_CLEAR]], %[[BF_SHIFT]]
436f20744bSErich Keane   // CHECK: store i16 %[[BF_SET]], ptr %[[S1]]
446f20744bSErich Keane   // CHECK: br label %[[END:.+]]
456f20744bSErich Keane 
46c9e9a7f2SNikita Popov   // CHECK: [[END]]:
476f20744bSErich Keane   // There is nothing in the 'end' block associated with this, but it is the
486f20744bSErich Keane   // 'continuation' block for the rest of the function.
496f20744bSErich Keane 
506f20744bSErich Keane   // Same test, has a no-op cast and parens.
516f20744bSErich Keane   (void)(cond ? s2.field1 = val1 : s2.field2 = val2);
526f20744bSErich Keane   // Condition setup, branch.
536f20744bSErich Keane   // CHECK: %[[CONDLD:.+]] = load i8, ptr %[[COND]]
546f20744bSErich Keane   // CHECK: %[[TO_BOOL:.+]] = trunc i8 %[[CONDLD]] to i1
556f20744bSErich Keane   // CHECK: br i1 %[[TO_BOOL]], label %[[TRUE:.+]], label %[[FALSE:.+]]
566f20744bSErich Keane 
576f20744bSErich Keane   // 'True', branch set the BF, branch to 'end'.
586f20744bSErich Keane   // CHECK: [[TRUE]]:
596f20744bSErich Keane   // CHECK: %[[VAL1LD:.+]] = load i32, ptr %[[VAL1]]
606f20744bSErich Keane   // CHECK: %[[VAL1TRUNC:.+]] = trunc i32 %[[VAL1LD]] to i16
616f20744bSErich Keane   // CHECK: %[[BF_LOAD:.+]] = load i16, ptr %[[S2]]
626f20744bSErich Keane   // CHECK: %[[BF_VAL:.+]] = and i16 %[[VAL1TRUNC]], 31
636f20744bSErich Keane   // CHECK: %[[BF_CLEAR:.+]] = and i16 %[[BF_LOAD]], -32
646f20744bSErich Keane   // CHECK: %[[BF_SET:.+]] = or i16 %[[BF_CLEAR]], %[[BF_VAL]]
656f20744bSErich Keane   // CHECK: store i16 %[[BF_SET]], ptr %[[S2]]
666f20744bSErich Keane   // CHECK: br label %[[END:.+]]
676f20744bSErich Keane 
686f20744bSErich Keane   // 'False', branch set the OTHER BF, branch to 'end'.
696f20744bSErich Keane   // CHECK: [[FALSE]]:
706f20744bSErich Keane   // CHECK: %[[VAL2LD:.+]] = load i32, ptr %[[VAL2]]
716f20744bSErich Keane   // CHECK: %[[VAL2TRUNC:.+]] = trunc i32 %[[VAL2LD]] to i16
726f20744bSErich Keane   // CHECK: %[[BF_LOAD:.+]] = load i16, ptr %[[S2]]
736f20744bSErich Keane   // CHECK: %[[BF_VAL:.+]] = and i16 %[[VAL2TRUNC]], 63
746f20744bSErich Keane   // CHECK: %[[BF_SHIFT:.+]] = shl i16 %[[BF_VAL]], 5
756f20744bSErich Keane   // CHECK: %[[BF_CLEAR:.+]] = and i16 %[[BF_LOAD]], -2017
766f20744bSErich Keane   // CHECK: %[[BF_SET:.+]] = or i16 %[[BF_CLEAR]], %[[BF_SHIFT]]
776f20744bSErich Keane   // CHECK: store i16 %[[BF_SET]], ptr %[[S2]]
786f20744bSErich Keane   // CHECK: br label %[[END:.+]]
796f20744bSErich Keane 
80c9e9a7f2SNikita Popov   // CHECK: [[END]]:
816f20744bSErich Keane   // CHECK-NOT: phi
826f20744bSErich Keane   // There is nothing in the 'end' block associated with this, but it is the
836f20744bSErich Keane   // 'continuation' block for the rest of the function.
846f20744bSErich Keane 
856f20744bSErich Keane }
866f20744bSErich Keane 
876f20744bSErich Keane 
use2(bool cond1,bool cond2,struct S s1,int val1,int val2,int val3)886f20744bSErich Keane void use2(bool cond1, bool cond2, struct S s1, int val1, int val2, int val3) {
89*cd50f910SSameer Sahasrabuddhe   // CHECK-LABEL: define {{.*}}use2{{.*}}(
906f20744bSErich Keane   // CHECK: %[[S1:.+]] = alloca %struct.S
916f20744bSErich Keane   // CHECK: %[[COND1:.+]] = alloca i8
926f20744bSErich Keane   // CHECK: %[[COND2:.+]] = alloca i8
936f20744bSErich Keane   // CHECK: %[[VAL1:.+]] = alloca i32
946f20744bSErich Keane   // CHECK: %[[VAL2:.+]] = alloca i32
956f20744bSErich Keane   // CHECK: %[[VAL3:.+]] = alloca i32
966f20744bSErich Keane 
976f20744bSErich Keane   cond1 ? s1.field1 = val1 : cond2 ? s1.field2 = val2 : s1.field3 = val3;
986f20744bSErich Keane   // First Condition setup, branch.
996f20744bSErich Keane   // CHECK: %[[CONDLD:.+]] = load i8, ptr %[[COND1]]
1006f20744bSErich Keane   // CHECK: %[[TO_BOOL:.+]] = trunc i8 %[[CONDLD]] to i1
1016f20744bSErich Keane   // CHECK: br i1 %[[TO_BOOL]], label %[[TRUE:.+]], label %[[FALSE:.+]]
1026f20744bSErich Keane 
1036f20744bSErich Keane   // First 'True' branch, sets field1 to val1.
1046f20744bSErich Keane   // CHECK: [[TRUE]]:
1056f20744bSErich Keane   // CHECK: %[[VAL1LD:.+]] = load i32, ptr %[[VAL1]]
1066f20744bSErich Keane   // CHECK: %[[VAL1TRUNC:.+]] = trunc i32 %[[VAL1LD]] to i16
1076f20744bSErich Keane   // CHECK: %[[BF_LOAD:.+]] = load i16, ptr %[[S1]]
1086f20744bSErich Keane   // CHECK: %[[BF_VAL:.+]] = and i16 %[[VAL1TRUNC]], 31
1096f20744bSErich Keane   // CHECK: %[[BF_CLEAR:.+]] = and i16 %[[BF_LOAD]], -32
1106f20744bSErich Keane   // CHECK: %[[BF_SET:.+]] = or i16 %[[BF_CLEAR]], %[[BF_VAL]]
1116f20744bSErich Keane   // CHECK: store i16 %[[BF_SET]], ptr %[[S1]]
1126f20744bSErich Keane   // CHECK: br label %[[END:.+]]
1136f20744bSErich Keane 
1146f20744bSErich Keane   // First 'False' branch, starts second ignored expression.
1156f20744bSErich Keane   // CHECK: [[FALSE]]:
1166f20744bSErich Keane   // CHECK: %[[CONDLD:.+]] = load i8, ptr %[[COND2]]
1176f20744bSErich Keane   // CHECK: %[[TO_BOOL:.+]] = trunc i8 %[[CONDLD]] to i1
1186f20744bSErich Keane   // CHECK: br i1 %[[TO_BOOL]], label %[[TRUE2:.+]], label %[[FALSE2:.+]]
1196f20744bSErich Keane 
1206f20744bSErich Keane   // Second 'True' branch, sets field2 to val2.
1216f20744bSErich Keane   // CHECK: [[TRUE2]]:
1226f20744bSErich Keane   // CHECK: %[[VAL2LD:.+]] = load i32, ptr %[[VAL2]]
1236f20744bSErich Keane   // CHECK: %[[VAL2TRUNC:.+]] = trunc i32 %[[VAL2LD]] to i16
1246f20744bSErich Keane   // CHECK: %[[BF_LOAD:.+]] = load i16, ptr %[[S1]]
1256f20744bSErich Keane   // CHECK: %[[BF_VAL:.+]] = and i16 %[[VAL2TRUNC]], 63
1266f20744bSErich Keane   // CHECK: %[[BF_SHIFT:.+]] = shl i16 %[[BF_VAL]], 5
1276f20744bSErich Keane   // CHECK: %[[BF_CLEAR:.+]] = and i16 %[[BF_LOAD]], -2017
1286f20744bSErich Keane   // CHECK: %[[BF_SET:.+]] = or i16 %[[BF_CLEAR]], %[[BF_SHIFT]]
1296f20744bSErich Keane   // CHECK: store i16 %[[BF_SET]], ptr %[[S1]]
1306f20744bSErich Keane   // CHECK: br label %[[END:.+]]
1316f20744bSErich Keane 
1326f20744bSErich Keane   // Second 'False' branch, sets field3 to val3.
1336f20744bSErich Keane   // CHECK: [[FALSE2]]:
1346f20744bSErich Keane   // CHECK: %[[VAL3LD:.+]] = load i32, ptr %[[VAL3]]
1356f20744bSErich Keane   // CHECK: %[[VAL3TRUNC:.+]] = trunc i32 %[[VAL3LD]] to i16
1366f20744bSErich Keane   // CHECK: %[[BF_LOAD:.+]] = load i16, ptr %[[S1]]
1376f20744bSErich Keane   // CHECK: %[[BF_VAL:.+]] = and i16 %[[VAL3TRUNC]], 7
1386f20744bSErich Keane   // CHECK: %[[BF_SHIFT:.+]] = shl i16 %[[BF_VAL]], 11
1396f20744bSErich Keane   // CHECK: %[[BF_CLEAR:.+]] = and i16 %[[BF_LOAD]], -14337
1406f20744bSErich Keane   // CHECK: %[[BF_SET:.+]] = or i16 %[[BF_CLEAR]], %[[BF_SHIFT]]
1416f20744bSErich Keane   // CHECK: store i16 %[[BF_SET]], ptr %[[S1]]
1426f20744bSErich Keane   // CHECK: br label %[[END:.+]]
1436f20744bSErich Keane 
144*cd50f910SSameer Sahasrabuddhe   // CHECK: [[END]]:
1456f20744bSErich Keane   // CHECK-NOT: phi
1466f20744bSErich Keane   // Nothing left to do here.
1476f20744bSErich Keane }
148*cd50f910SSameer Sahasrabuddhe 
149*cd50f910SSameer Sahasrabuddhe // Catch the end of the IR. This prevents the CHECK-NOT above from matching a
150*cd50f910SSameer Sahasrabuddhe // spurious "phi" in file paths printed in the output.
151*cd50f910SSameer Sahasrabuddhe // CHECK-LABEL: attributes
152