|
| 1 | +// RUN: %dxc -T ps_6_0 -E main -HV 2021 |
| 2 | + |
| 3 | +// CHECK: [[v3i0:%\d+]] = OpConstantComposite %v3int %int_0 %int_0 %int_0 |
| 4 | + |
| 5 | +uint foo() { return 1; } |
| 6 | +float bar() { return 3.0; } |
| 7 | +uint zoo(); |
| 8 | + |
| 9 | +void main() { |
| 10 | + // CHECK-LABEL: %bb_entry = OpLabel |
| 11 | + |
| 12 | + // CHECK: %temp_var_ternary = OpVariable %_ptr_Function_mat2v3float Function |
| 13 | + // CHECK: %temp_var_ternary_0 = OpVariable %_ptr_Function_mat2v3float Function |
| 14 | + |
| 15 | + bool b0; |
| 16 | + int m, n, o; |
| 17 | + // Plain assign (scalar) |
| 18 | + // CHECK: [[b0:%\d+]] = OpLoad %bool %b0 |
| 19 | + // CHECK-NEXT: [[m0:%\d+]] = OpLoad %int %m |
| 20 | + // CHECK-NEXT: [[n0:%\d+]] = OpLoad %int %n |
| 21 | + // CHECK-NEXT: [[s0:%\d+]] = OpSelect %int [[b0]] [[m0]] [[n0]] |
| 22 | + // CHECK-NEXT: OpStore %o [[s0]] |
| 23 | + o = select(b0, m, n); |
| 24 | + |
| 25 | + bool1 b1; |
| 26 | + bool3 b3; |
| 27 | + uint1 p, q, r; |
| 28 | + float3 x, y, z; |
| 29 | + // Plain assign (vector) |
| 30 | + // CHECK-NEXT: [[b1:%\d+]] = OpLoad %bool %b1 |
| 31 | + // CHECK-NEXT: [[p0:%\d+]] = OpLoad %uint %p |
| 32 | + // CHECK-NEXT: [[q0:%\d+]] = OpLoad %uint %q |
| 33 | + // CHECK-NEXT: [[s1:%\d+]] = OpSelect %uint [[b1]] [[p0]] [[q0]] |
| 34 | + // CHECK-NEXT: OpStore %r [[s1]] |
| 35 | + r = select(b1, p, q); |
| 36 | + // CHECK-NEXT: [[b3:%\d+]] = OpLoad %v3bool %b3 |
| 37 | + // CHECK-NEXT: [[x0:%\d+]] = OpLoad %v3float %x |
| 38 | + // CHECK-NEXT: [[y0:%\d+]] = OpLoad %v3float %y |
| 39 | + // CHECK-NEXT: [[s2:%\d+]] = OpSelect %v3float [[b3]] [[x0]] [[y0]] |
| 40 | + // CHECK-NEXT: OpStore %z [[s2]] |
| 41 | + z = select(b3, x, y); |
| 42 | + |
| 43 | + // Try condition with various type. |
| 44 | + // Note: the SPIR-V OpSelect selection argument must be the same size as the return type. |
| 45 | + int3 u, v, w; |
| 46 | + float2x3 umat, vmat, wmat; |
| 47 | + bool cond; |
| 48 | + bool3 cond3; |
| 49 | + float floatCond; |
| 50 | + int intCond; |
| 51 | + int3 int3Cond; |
| 52 | + |
| 53 | + // CHECK: [[cond3:%\d+]] = OpLoad %v3bool %cond3 |
| 54 | + // CHECK-NEXT: [[u:%\d+]] = OpLoad %v3int %u |
| 55 | + // CHECK-NEXT: [[v:%\d+]] = OpLoad %v3int %v |
| 56 | + // CHECK-NEXT: {{%\d+}} = OpSelect %v3int [[cond3]] [[u]] [[v]] |
| 57 | + w = select(cond3, u, v); |
| 58 | + |
| 59 | + // CHECK: [[cond:%\d+]] = OpLoad %bool %cond |
| 60 | + // CHECK-NEXT: [[splat:%\d+]] = OpCompositeConstruct %v3bool [[cond]] [[cond]] [[cond]] |
| 61 | + // CHECK-NEXT: [[u:%\d+]] = OpLoad %v3int %u |
| 62 | + // CHECK-NEXT: [[v:%\d+]] = OpLoad %v3int %v |
| 63 | + // CHECK-NEXT: {{%\d+}} = OpSelect %v3int [[splat]] [[u]] [[v]] |
| 64 | + w = select(cond, u, v); |
| 65 | + |
| 66 | + // CHECK: [[floatCond:%\d+]] = OpLoad %float %floatCond |
| 67 | + // CHECK-NEXT: [[boolCond:%\d+]] = OpFOrdNotEqual %bool [[floatCond]] %float_0 |
| 68 | + // CHECK-NEXT: [[bool3Cond:%\d+]] = OpCompositeConstruct %v3bool [[boolCond]] [[boolCond]] [[boolCond]] |
| 69 | + // CHECK-NEXT: [[u:%\d+]] = OpLoad %v3int %u |
| 70 | + // CHECK-NEXT: [[v:%\d+]] = OpLoad %v3int %v |
| 71 | + // CHECK-NEXT: {{%\d+}} = OpSelect %v3int [[bool3Cond]] [[u]] [[v]] |
| 72 | + w = select(floatCond, u, v); |
| 73 | + |
| 74 | + // CHECK: [[int3Cond:%\d+]] = OpLoad %v3int %int3Cond |
| 75 | + // CHECK-NEXT: [[bool3Cond:%\d+]] = OpINotEqual %v3bool [[int3Cond]] [[v3i0]] |
| 76 | + // CHECK-NEXT: [[u:%\d+]] = OpLoad %v3int %u |
| 77 | + // CHECK-NEXT: [[v:%\d+]] = OpLoad %v3int %v |
| 78 | + // CHECK-NEXT: {{%\d+}} = OpSelect %v3int [[bool3Cond]] [[u]] [[v]] |
| 79 | + w = select(int3Cond, u, v); |
| 80 | + |
| 81 | + // CHECK: [[intCond:%\d+]] = OpLoad %int %intCond |
| 82 | + // CHECK-NEXT: [[boolCond:%\d+]] = OpINotEqual %bool [[intCond]] %int_0 |
| 83 | + // CHECK-NEXT: [[umat:%\d+]] = OpLoad %mat2v3float %umat |
| 84 | + // CHECK-NEXT: [[vmat:%\d+]] = OpLoad %mat2v3float %vmat |
| 85 | + // CHECK-NEXT: OpSelectionMerge %if_merge None |
| 86 | + // CHECK-NEXT: OpBranchConditional [[boolCond]] %if_true %if_false |
| 87 | + // CHECK-NEXT: %if_true = OpLabel |
| 88 | + // CHECK-NEXT: OpStore %temp_var_ternary [[umat]] |
| 89 | + // CHECK-NEXT: OpBranch %if_merge |
| 90 | + // CHECK-NEXT: %if_false = OpLabel |
| 91 | + // CHECK-NEXT: OpStore %temp_var_ternary [[vmat]] |
| 92 | + // CHECK-NEXT: OpBranch %if_merge |
| 93 | + // CHECK-NEXT: %if_merge = OpLabel |
| 94 | + // CHECK-NEXT: [[tempVar:%\d+]] = OpLoad %mat2v3float %temp_var_ternary |
| 95 | + // CHECK-NEXT: OpStore %wmat [[tempVar]] |
| 96 | + wmat = select(intCond, umat, vmat); |
| 97 | + |
| 98 | + // Make sure literal types are handled correctly in ternary ops |
| 99 | + |
| 100 | + // CHECK: [[b_float:%\d+]] = OpSelect %float {{%\d+}} %float_1_5 %float_2_5 |
| 101 | + // CHECK-NEXT: {{%\d+}} = OpConvertFToS %int [[b_float]] |
| 102 | + int b = select(cond, 1.5, 2.5); |
| 103 | + |
| 104 | + // CHECK: [[a_int:%\d+]] = OpSelect %int {{%\d+}} %int_1 %int_0 |
| 105 | + // CHECK-NEXT: {{%\d+}} = OpConvertSToF %float [[a_int]] |
| 106 | + float a = select(cond, 1, 0); |
| 107 | + |
| 108 | + // CHECK: [[c_long:%\d+]] = OpSelect %long {{%\d+}} %long_3000000000 %long_4000000000 |
| 109 | + double c = select(cond, 3000000000, 4000000000); |
| 110 | + |
| 111 | + // CHECK: [[d_int:%\d+]] = OpSelect %uint {{%\d+}} %uint_1 %uint_0 |
| 112 | + uint d = select(cond, 1, 0); |
| 113 | + |
| 114 | + float2x3 e; |
| 115 | + float2x3 f; |
| 116 | + // CHECK: [[cond:%\d+]] = OpLoad %bool %cond |
| 117 | + // CHECK-NEXT: [[e:%\d+]] = OpLoad %mat2v3float %e |
| 118 | + // CHECK-NEXT: [[f:%\d+]] = OpLoad %mat2v3float %f |
| 119 | + // CHECK-NEXT: OpSelectionMerge %if_merge_0 None |
| 120 | + // CHECK-NEXT: OpBranchConditional [[cond]] %if_true_0 %if_false_0 |
| 121 | + // CHECK-NEXT: %if_true_0 = OpLabel |
| 122 | + // CHECK-NEXT: OpStore %temp_var_ternary_0 [[e]] |
| 123 | + // CHECK-NEXT: OpBranch %if_merge_0 |
| 124 | + // CHECK-NEXT: %if_false_0 = OpLabel |
| 125 | + // CHECK-NEXT: OpStore %temp_var_ternary_0 [[f]] |
| 126 | + // CHECK-NEXT: OpBranch %if_merge_0 |
| 127 | + // CHECK-NEXT: %if_merge_0 = OpLabel |
| 128 | + // CHECK-NEXT:[[temp:%\d+]] = OpLoad %mat2v3float %temp_var_ternary_0 |
| 129 | + // CHECK-NEXT: OpStore %g [[temp]] |
| 130 | + float2x3 g = select(cond, e, f); |
| 131 | + |
| 132 | + // CHECK: [[inner:%\d+]] = OpSelect %uint {{%\d+}} %uint_1 %uint_2 |
| 133 | + // CHECK-NEXT: {{%\d+}} = OpSelect %uint {{%\d+}} %uint_9 [[inner]] |
| 134 | + uint h = select(cond, 9, select(cond, 1, 2)); |
| 135 | + |
| 136 | + //CHECK: [[i_int:%\d+]] = OpSelect %int {{%\d+}} %int_1 %int_0 |
| 137 | + //CHECK-NEXT: {{%\d+}} = OpINotEqual %bool [[i_int]] %int_0 |
| 138 | + bool i = select(cond, 1, 0); |
| 139 | + |
| 140 | + // CHECK: [[foo:%\d+]] = OpFunctionCall %uint %foo |
| 141 | + // CHECKNEXT: {{%\d+}} = OpSelect %uint {{%\d+}} %uint_3 [[foo]] |
| 142 | + uint j = select(cond, 3, foo()); |
| 143 | + |
| 144 | + // CHECK: [[bar:%\d+]] = OpFunctionCall %float %bar |
| 145 | + // CHECK-NEXT: [[k_float:%\d+]] = OpSelect %float {{%\d+}} %float_4 [[bar]] |
| 146 | + // CHECK-NEXT: {{%\d+}} = OpConvertFToU %uint [[k_float]] |
| 147 | + uint k = select(cond, 4, bar()); |
| 148 | + |
| 149 | + zoo(); |
| 150 | + |
| 151 | + // CHECK: [[cond2x3:%\d+]] = OpLoad %_arr_v3bool_uint_2 %cond2x3 |
| 152 | + // CHECK-NEXT: [[true2x3:%\d+]] = OpLoad %mat2v3float %true2x3 |
| 153 | + // CHECK-NEXT: [[false2x3:%\d+]] = OpLoad %mat2v3float %false2x3 |
| 154 | + // CHECK-NEXT: [[c0:%\d+]] = OpCompositeExtract %v3bool [[cond2x3]] 0 |
| 155 | + // CHECK-NEXT: [[t0:%\d+]] = OpCompositeExtract %v3float [[true2x3]] 0 |
| 156 | + // CHECK-NEXT: [[f0:%\d+]] = OpCompositeExtract %v3float [[false2x3]] 0 |
| 157 | + // CHECK-NEXT: [[r0:%\d+]] = OpSelect %v3float [[c0]] [[t0]] [[f0]] |
| 158 | + // CHECK-NEXT: [[c1:%\d+]] = OpCompositeExtract %v3bool [[cond2x3]] 1 |
| 159 | + // CHECK-NEXT: [[t1:%\d+]] = OpCompositeExtract %v3float [[true2x3]] 1 |
| 160 | + // CHECK-NEXT: [[f1:%\d+]] = OpCompositeExtract %v3float [[false2x3]] 1 |
| 161 | + // CHECK-NEXT: [[r1:%\d+]] = OpSelect %v3float [[c1]] [[t1]] [[f1]] |
| 162 | + // CHECK-NEXT: [[result:%\d+]] = OpCompositeConstruct %mat2v3float [[r0]] [[r1]] |
| 163 | + // CHECK-NEXT: OpStore %result2x3 [[result]] |
| 164 | + bool2x3 cond2x3; |
| 165 | + float2x3 true2x3, false2x3; |
| 166 | + float2x3 result2x3 = select(cond2x3, true2x3, false2x3); |
| 167 | +} |
| 168 | + |
| 169 | +// |
| 170 | +// The literal integer type should be deduced from the function return type. |
| 171 | +// |
| 172 | +// CHECK: OpSelect %uint {{%\d+}} %uint_1 %uint_2 |
| 173 | +uint zoo() { |
| 174 | + bool cond; |
| 175 | + return select(cond, 1, 2); |
| 176 | +} |
| 177 | + |
0 commit comments