1 // RUN: %clang_cc1 -triple x86_64-unknown-linux-gnu -emit-llvm -o - %s | FileCheck %s 2 3 struct S { 4 int field1 : 5; 5 int field2 : 6; 6 int field3 : 3; 7 }; 8 9 void use(bool cond, struct S s1, struct S s2, int val1, int val2) { 10 // CHECK: define {{.*}}use{{.*}}( 11 // CHECK: %[[S1:.+]] = alloca %struct.S 12 // CHECK: %[[S2:.+]] = alloca %struct.S 13 // CHECK: %[[COND:.+]] = alloca i8 14 // CHECK: %[[VAL1:.+]] = alloca i32 15 // CHECK: %[[VAL2:.+]] = alloca i32 16 17 cond ? s1.field1 = val1 : s1.field2 = val2; 18 // Condition setup, branch. 19 // CHECK: %[[CONDLD:.+]] = load i8, ptr %[[COND]] 20 // CHECK: %[[TO_BOOL:.+]] = trunc i8 %[[CONDLD]] to i1 21 // CHECK: br i1 %[[TO_BOOL]], label %[[TRUE:.+]], label %[[FALSE:.+]] 22 23 // 'True', branch set the BF, branch to 'end'. 24 // CHECK: [[TRUE]]: 25 // CHECK: %[[VAL1LD:.+]] = load i32, ptr %[[VAL1]] 26 // CHECK: %[[VAL1TRUNC:.+]] = trunc i32 %[[VAL1LD]] to i16 27 // CHECK: %[[BF_LOAD:.+]] = load i16, ptr %[[S1]] 28 // CHECK: %[[BF_VAL:.+]] = and i16 %[[VAL1TRUNC]], 31 29 // CHECK: %[[BF_CLEAR:.+]] = and i16 %[[BF_LOAD]], -32 30 // CHECK: %[[BF_SET:.+]] = or i16 %[[BF_CLEAR]], %[[BF_VAL]] 31 // CHECK: store i16 %[[BF_SET]], ptr %[[S1]] 32 // CHECK: br label %[[END:.+]] 33 34 // 'False', branch set the OTHER BF, branch to 'end'. 35 // CHECK: [[FALSE]]: 36 // CHECK: %[[VAL2LD:.+]] = load i32, ptr %[[VAL2]] 37 // CHECK: %[[VAL2TRUNC:.+]] = trunc i32 %[[VAL2LD]] to i16 38 // CHECK: %[[BF_LOAD:.+]] = load i16, ptr %[[S1]] 39 // CHECK: %[[BF_VAL:.+]] = and i16 %[[VAL2TRUNC]], 63 40 // CHECK: %[[BF_SHIFT:.+]] = shl i16 %[[BF_VAL]], 5 41 // CHECK: %[[BF_CLEAR:.+]] = and i16 %[[BF_LOAD]], -2017 42 // CHECK: %[[BF_SET:.+]] = or i16 %[[BF_CLEAR]], %[[BF_SHIFT]] 43 // CHECK: store i16 %[[BF_SET]], ptr %[[S1]] 44 // CHECK: br label %[[END:.+]] 45 46 // CHECK: [[END]]: 47 // There is nothing in the 'end' block associated with this, but it is the 48 // 'continuation' block for the rest of the function. 49 50 // Same test, has a no-op cast and parens. 51 (void)(cond ? s2.field1 = val1 : s2.field2 = val2); 52 // Condition setup, branch. 53 // CHECK: %[[CONDLD:.+]] = load i8, ptr %[[COND]] 54 // CHECK: %[[TO_BOOL:.+]] = trunc i8 %[[CONDLD]] to i1 55 // CHECK: br i1 %[[TO_BOOL]], label %[[TRUE:.+]], label %[[FALSE:.+]] 56 57 // 'True', branch set the BF, branch to 'end'. 58 // CHECK: [[TRUE]]: 59 // CHECK: %[[VAL1LD:.+]] = load i32, ptr %[[VAL1]] 60 // CHECK: %[[VAL1TRUNC:.+]] = trunc i32 %[[VAL1LD]] to i16 61 // CHECK: %[[BF_LOAD:.+]] = load i16, ptr %[[S2]] 62 // CHECK: %[[BF_VAL:.+]] = and i16 %[[VAL1TRUNC]], 31 63 // CHECK: %[[BF_CLEAR:.+]] = and i16 %[[BF_LOAD]], -32 64 // CHECK: %[[BF_SET:.+]] = or i16 %[[BF_CLEAR]], %[[BF_VAL]] 65 // CHECK: store i16 %[[BF_SET]], ptr %[[S2]] 66 // CHECK: br label %[[END:.+]] 67 68 // 'False', branch set the OTHER BF, branch to 'end'. 69 // CHECK: [[FALSE]]: 70 // CHECK: %[[VAL2LD:.+]] = load i32, ptr %[[VAL2]] 71 // CHECK: %[[VAL2TRUNC:.+]] = trunc i32 %[[VAL2LD]] to i16 72 // CHECK: %[[BF_LOAD:.+]] = load i16, ptr %[[S2]] 73 // CHECK: %[[BF_VAL:.+]] = and i16 %[[VAL2TRUNC]], 63 74 // CHECK: %[[BF_SHIFT:.+]] = shl i16 %[[BF_VAL]], 5 75 // CHECK: %[[BF_CLEAR:.+]] = and i16 %[[BF_LOAD]], -2017 76 // CHECK: %[[BF_SET:.+]] = or i16 %[[BF_CLEAR]], %[[BF_SHIFT]] 77 // CHECK: store i16 %[[BF_SET]], ptr %[[S2]] 78 // CHECK: br label %[[END:.+]] 79 80 // CHECK: [[END]]: 81 // CHECK-NOT: phi 82 // There is nothing in the 'end' block associated with this, but it is the 83 // 'continuation' block for the rest of the function. 84 85 } 86 87 88 void use2(bool cond1, bool cond2, struct S s1, int val1, int val2, int val3) { 89 // CHECK: define {{.*}}use2{{.*}}( 90 // CHECK: %[[S1:.+]] = alloca %struct.S 91 // CHECK: %[[COND1:.+]] = alloca i8 92 // CHECK: %[[COND2:.+]] = alloca i8 93 // CHECK: %[[VAL1:.+]] = alloca i32 94 // CHECK: %[[VAL2:.+]] = alloca i32 95 // CHECK: %[[VAL3:.+]] = alloca i32 96 97 cond1 ? s1.field1 = val1 : cond2 ? s1.field2 = val2 : s1.field3 = val3; 98 // First Condition setup, branch. 99 // CHECK: %[[CONDLD:.+]] = load i8, ptr %[[COND1]] 100 // CHECK: %[[TO_BOOL:.+]] = trunc i8 %[[CONDLD]] to i1 101 // CHECK: br i1 %[[TO_BOOL]], label %[[TRUE:.+]], label %[[FALSE:.+]] 102 103 // First 'True' branch, sets field1 to val1. 104 // CHECK: [[TRUE]]: 105 // CHECK: %[[VAL1LD:.+]] = load i32, ptr %[[VAL1]] 106 // CHECK: %[[VAL1TRUNC:.+]] = trunc i32 %[[VAL1LD]] to i16 107 // CHECK: %[[BF_LOAD:.+]] = load i16, ptr %[[S1]] 108 // CHECK: %[[BF_VAL:.+]] = and i16 %[[VAL1TRUNC]], 31 109 // CHECK: %[[BF_CLEAR:.+]] = and i16 %[[BF_LOAD]], -32 110 // CHECK: %[[BF_SET:.+]] = or i16 %[[BF_CLEAR]], %[[BF_VAL]] 111 // CHECK: store i16 %[[BF_SET]], ptr %[[S1]] 112 // CHECK: br label %[[END:.+]] 113 114 // First 'False' branch, starts second ignored expression. 115 // CHECK: [[FALSE]]: 116 // CHECK: %[[CONDLD:.+]] = load i8, ptr %[[COND2]] 117 // CHECK: %[[TO_BOOL:.+]] = trunc i8 %[[CONDLD]] to i1 118 // CHECK: br i1 %[[TO_BOOL]], label %[[TRUE2:.+]], label %[[FALSE2:.+]] 119 120 // Second 'True' branch, sets field2 to val2. 121 // CHECK: [[TRUE2]]: 122 // CHECK: %[[VAL2LD:.+]] = load i32, ptr %[[VAL2]] 123 // CHECK: %[[VAL2TRUNC:.+]] = trunc i32 %[[VAL2LD]] to i16 124 // CHECK: %[[BF_LOAD:.+]] = load i16, ptr %[[S1]] 125 // CHECK: %[[BF_VAL:.+]] = and i16 %[[VAL2TRUNC]], 63 126 // CHECK: %[[BF_SHIFT:.+]] = shl i16 %[[BF_VAL]], 5 127 // CHECK: %[[BF_CLEAR:.+]] = and i16 %[[BF_LOAD]], -2017 128 // CHECK: %[[BF_SET:.+]] = or i16 %[[BF_CLEAR]], %[[BF_SHIFT]] 129 // CHECK: store i16 %[[BF_SET]], ptr %[[S1]] 130 // CHECK: br label %[[END:.+]] 131 132 // Second 'False' branch, sets field3 to val3. 133 // CHECK: [[FALSE2]]: 134 // CHECK: %[[VAL3LD:.+]] = load i32, ptr %[[VAL3]] 135 // CHECK: %[[VAL3TRUNC:.+]] = trunc i32 %[[VAL3LD]] to i16 136 // CHECK: %[[BF_LOAD:.+]] = load i16, ptr %[[S1]] 137 // CHECK: %[[BF_VAL:.+]] = and i16 %[[VAL3TRUNC]], 7 138 // CHECK: %[[BF_SHIFT:.+]] = shl i16 %[[BF_VAL]], 11 139 // CHECK: %[[BF_CLEAR:.+]] = and i16 %[[BF_LOAD]], -14337 140 // CHECK: %[[BF_SET:.+]] = or i16 %[[BF_CLEAR]], %[[BF_SHIFT]] 141 // CHECK: store i16 %[[BF_SET]], ptr %[[S1]] 142 // CHECK: br label %[[END:.+]] 143 144 // CHECK[[END]]: 145 // CHECK-NOT: phi 146 // Nothing left to do here. 147 } 148