1 /*
2 * Copyright © 2015 Intel Corporation
3 *
4 * Permission is hereby granted, free of charge, to any person obtaining a
5 * copy of this software and associated documentation files (the "Software"),
6 * to deal in the Software without restriction, including without limitation
7 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8 * and/or sell copies of the Software, and to permit persons to whom the
9 * Software is furnished to do so, subject to the following conditions:
10 *
11 * The above copyright notice and this permission notice (including the next
12 * paragraph) shall be included in all copies or substantial portions of the
13 * Software.
14 *
15 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
18 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
20 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
21 * IN THE SOFTWARE.
22 *
23 * Based on test_fs_cmod_propagation.cpp
24 */
25
26 #include <gtest/gtest.h>
27 #include "elk_vec4.h"
28 #include "elk_vec4_builder.h"
29 #include "elk_cfg.h"
30
31 using namespace elk;
32
33 class cmod_propagation_vec4_test : public ::testing::Test {
34 virtual void SetUp();
35 virtual void TearDown();
36
37 public:
38 struct elk_compiler *compiler;
39 struct elk_compile_params params;
40 struct intel_device_info *devinfo;
41 void *ctx;
42 struct gl_shader_program *shader_prog;
43 struct elk_vue_prog_data *prog_data;
44 vec4_visitor *v;
45 };
46
47 class cmod_propagation_vec4_visitor : public vec4_visitor
48 {
49 public:
cmod_propagation_vec4_visitor(struct elk_compiler * compiler,struct elk_compile_params * params,nir_shader * shader,struct elk_vue_prog_data * prog_data)50 cmod_propagation_vec4_visitor(struct elk_compiler *compiler,
51 struct elk_compile_params *params,
52 nir_shader *shader,
53 struct elk_vue_prog_data *prog_data)
54 : vec4_visitor(compiler, params, NULL, prog_data, shader,
55 false, false)
56 {
57 prog_data->dispatch_mode = INTEL_DISPATCH_MODE_4X2_DUAL_OBJECT;
58 }
59
60 protected:
61 /* Dummy implementation for pure virtual methods */
make_reg_for_system_value(int)62 virtual dst_reg *make_reg_for_system_value(int /* location */)
63 {
64 unreachable("Not reached");
65 }
66
setup_payload()67 virtual void setup_payload()
68 {
69 unreachable("Not reached");
70 }
71
emit_prolog()72 virtual void emit_prolog()
73 {
74 unreachable("Not reached");
75 }
76
emit_program_code()77 virtual void emit_program_code()
78 {
79 unreachable("Not reached");
80 }
81
emit_thread_end()82 virtual void emit_thread_end()
83 {
84 unreachable("Not reached");
85 }
86
emit_urb_write_header(int)87 virtual void emit_urb_write_header(int /* mrf */)
88 {
89 unreachable("Not reached");
90 }
91
emit_urb_write_opcode(bool)92 virtual vec4_instruction *emit_urb_write_opcode(bool /* complete */)
93 {
94 unreachable("Not reached");
95 }
96 };
97
98
SetUp()99 void cmod_propagation_vec4_test::SetUp()
100 {
101 ctx = ralloc_context(NULL);
102 compiler = rzalloc(ctx, struct elk_compiler);
103 devinfo = rzalloc(ctx, struct intel_device_info);
104 compiler->devinfo = devinfo;
105
106 params = {};
107 params.mem_ctx = ctx;
108
109 prog_data = ralloc(ctx, struct elk_vue_prog_data);
110 nir_shader *shader =
111 nir_shader_create(ctx, MESA_SHADER_VERTEX, NULL, NULL);
112
113 v = new cmod_propagation_vec4_visitor(compiler, ¶ms, shader, prog_data);
114
115 devinfo->ver = 7;
116 devinfo->verx10 = devinfo->ver * 10;
117 }
118
TearDown()119 void cmod_propagation_vec4_test::TearDown()
120 {
121 delete v;
122 v = NULL;
123
124 ralloc_free(ctx);
125 ctx = NULL;
126 }
127
128 static vec4_instruction *
instruction(elk_bblock_t * block,int num)129 instruction(elk_bblock_t *block, int num)
130 {
131 vec4_instruction *inst = (vec4_instruction *)block->start();
132 for (int i = 0; i < num; i++) {
133 inst = (vec4_instruction *)inst->next;
134 }
135 return inst;
136 }
137
138 static bool
cmod_propagation(vec4_visitor * v)139 cmod_propagation(vec4_visitor *v)
140 {
141 const bool print = getenv("TEST_DEBUG");
142
143 if (print) {
144 fprintf(stderr, "= Before =\n");
145 v->dump_instructions();
146 }
147
148 bool ret = v->opt_cmod_propagation();
149
150 if (print) {
151 fprintf(stderr, "\n= After =\n");
152 v->dump_instructions();
153 }
154
155 return ret;
156 }
157
TEST_F(cmod_propagation_vec4_test,basic)158 TEST_F(cmod_propagation_vec4_test, basic)
159 {
160 const vec4_builder bld = vec4_builder(v).at_end();
161 dst_reg dest = dst_reg(v, glsl_float_type());
162 src_reg src0 = src_reg(v, glsl_float_type());
163 src_reg src1 = src_reg(v, glsl_float_type());
164 src_reg zero(elk_imm_f(0.0f));
165 dst_reg dest_null = bld.null_reg_f();
166 dest_null.writemask = WRITEMASK_X;
167
168 bld.ADD(dest, src0, src1);
169 bld.CMP(dest_null, src_reg(dest), zero, ELK_CONDITIONAL_GE);
170
171 /* = Before =
172 *
173 * 0: add dest.x src0.xxxx src1.xxxx
174 * 1: cmp.ge.f0 null.x dest.xxxx 0.0f
175 *
176 * = After =
177 * 0: add.ge.f0 dest.x src0.xxxx src1.xxxx
178 */
179
180 v->calculate_cfg();
181 elk_bblock_t *block0 = v->cfg->blocks[0];
182
183 EXPECT_EQ(0, block0->start_ip);
184 EXPECT_EQ(1, block0->end_ip);
185
186 EXPECT_TRUE(cmod_propagation(v));
187
188 ASSERT_EQ(0, block0->start_ip);
189 ASSERT_EQ(0, block0->end_ip);
190 EXPECT_EQ(ELK_OPCODE_ADD, instruction(block0, 0)->opcode);
191 EXPECT_EQ(ELK_CONDITIONAL_GE, instruction(block0, 0)->conditional_mod);
192 }
193
TEST_F(cmod_propagation_vec4_test,basic_different_dst_writemask)194 TEST_F(cmod_propagation_vec4_test, basic_different_dst_writemask)
195 {
196 const vec4_builder bld = vec4_builder(v).at_end();
197 dst_reg dest = dst_reg(v, glsl_float_type());
198 src_reg src0 = src_reg(v, glsl_float_type());
199 src_reg src1 = src_reg(v, glsl_float_type());
200 src_reg zero(elk_imm_f(0.0f));
201 dst_reg dest_null = bld.null_reg_f();
202
203 bld.ADD(dest, src0, src1);
204 bld.CMP(dest_null, src_reg(dest), zero, ELK_CONDITIONAL_GE);
205
206 /* = Before =
207 *
208 * 0: add dest.x src0 src1
209 * 1: cmp.ge.f0 null.xyzw dest 0.0f
210 *
211 * = After =
212 * (no changes)
213 */
214
215 v->calculate_cfg();
216 elk_bblock_t *block0 = v->cfg->blocks[0];
217
218 EXPECT_EQ(0, block0->start_ip);
219 EXPECT_EQ(1, block0->end_ip);
220
221 EXPECT_FALSE(cmod_propagation(v));
222
223 ASSERT_EQ(0, block0->start_ip);
224 ASSERT_EQ(1, block0->end_ip);
225 EXPECT_EQ(ELK_OPCODE_ADD, instruction(block0, 0)->opcode);
226 EXPECT_EQ(ELK_CONDITIONAL_NONE, instruction(block0, 0)->conditional_mod);
227 EXPECT_EQ(ELK_OPCODE_CMP, instruction(block0, 1)->opcode);
228 EXPECT_EQ(ELK_CONDITIONAL_GE, instruction(block0, 1)->conditional_mod);
229 }
230
TEST_F(cmod_propagation_vec4_test,andz_one)231 TEST_F(cmod_propagation_vec4_test, andz_one)
232 {
233 const vec4_builder bld = vec4_builder(v).at_end();
234 dst_reg dest = dst_reg(v, glsl_int_type());
235 src_reg src0 = src_reg(v, glsl_float_type());
236 src_reg zero(elk_imm_f(0.0f));
237 src_reg one(elk_imm_d(1));
238
239 bld.CMP(retype(dest, ELK_REGISTER_TYPE_F), src0, zero, ELK_CONDITIONAL_L);
240 set_condmod(ELK_CONDITIONAL_Z,
241 bld.AND(bld.null_reg_d(), src_reg(dest), one));
242
243 /* = Before =
244 * 0: cmp.l.f0 dest:F src0:F 0F
245 * 1: and.z.f0 null:D dest:D 1D
246 *
247 * = After =
248 * (no changes)
249 */
250
251 v->calculate_cfg();
252 elk_bblock_t *block0 = v->cfg->blocks[0];
253
254 EXPECT_EQ(0, block0->start_ip);
255 EXPECT_EQ(1, block0->end_ip);
256
257 EXPECT_FALSE(cmod_propagation(v));
258
259 ASSERT_EQ(0, block0->start_ip);
260 ASSERT_EQ(1, block0->end_ip);
261 EXPECT_EQ(ELK_OPCODE_CMP, instruction(block0, 0)->opcode);
262 EXPECT_EQ(ELK_CONDITIONAL_L, instruction(block0, 0)->conditional_mod);
263 EXPECT_EQ(ELK_OPCODE_AND, instruction(block0, 1)->opcode);
264 EXPECT_EQ(ELK_CONDITIONAL_EQ, instruction(block0, 1)->conditional_mod);
265 }
266
TEST_F(cmod_propagation_vec4_test,non_cmod_instruction)267 TEST_F(cmod_propagation_vec4_test, non_cmod_instruction)
268 {
269 const vec4_builder bld = vec4_builder(v).at_end();
270 dst_reg dest = dst_reg(v, glsl_uint_type());
271 src_reg src0 = src_reg(v, glsl_uint_type());
272 src_reg zero(elk_imm_ud(0u));
273 bld.FBL(dest, src0);
274 bld.CMP(bld.null_reg_ud(), src_reg(dest), zero, ELK_CONDITIONAL_GE);
275
276 /* = Before =
277 *
278 * 0: fbl dest src0
279 * 1: cmp.ge.f0 null dest 0u
280 *
281 * = After =
282 * (no changes)
283 */
284
285 v->calculate_cfg();
286 elk_bblock_t *block0 = v->cfg->blocks[0];
287
288 EXPECT_EQ(0, block0->start_ip);
289 EXPECT_EQ(1, block0->end_ip);
290
291 EXPECT_FALSE(cmod_propagation(v));
292
293 ASSERT_EQ(0, block0->start_ip);
294 ASSERT_EQ(1, block0->end_ip);
295 EXPECT_EQ(ELK_OPCODE_FBL, instruction(block0, 0)->opcode);
296 EXPECT_EQ(ELK_OPCODE_CMP, instruction(block0, 1)->opcode);
297 EXPECT_EQ(ELK_CONDITIONAL_GE, instruction(block0, 1)->conditional_mod);
298 }
299
TEST_F(cmod_propagation_vec4_test,intervening_flag_write)300 TEST_F(cmod_propagation_vec4_test, intervening_flag_write)
301 {
302 const vec4_builder bld = vec4_builder(v).at_end();
303 dst_reg dest = dst_reg(v, glsl_float_type());
304 src_reg src0 = src_reg(v, glsl_float_type());
305 src_reg src1 = src_reg(v, glsl_float_type());
306 src_reg src2 = src_reg(v, glsl_float_type());
307 src_reg zero(elk_imm_f(0.0f));
308 bld.ADD(dest, src0, src1);
309 bld.CMP(bld.null_reg_f(), src2, zero, ELK_CONDITIONAL_GE);
310 bld.CMP(bld.null_reg_f(), src_reg(dest), zero, ELK_CONDITIONAL_GE);
311
312 /* = Before =
313 *
314 * 0: add dest src0 src1
315 * 1: cmp.ge.f0 null src2 0.0f
316 * 2: cmp.ge.f0 null dest 0.0f
317 *
318 * = After =
319 * (no changes)
320 */
321
322 v->calculate_cfg();
323 elk_bblock_t *block0 = v->cfg->blocks[0];
324
325 EXPECT_EQ(0, block0->start_ip);
326 EXPECT_EQ(2, block0->end_ip);
327
328 EXPECT_FALSE(cmod_propagation(v));
329
330 ASSERT_EQ(0, block0->start_ip);
331 ASSERT_EQ(2, block0->end_ip);
332 EXPECT_EQ(ELK_OPCODE_ADD, instruction(block0, 0)->opcode);
333 EXPECT_EQ(ELK_OPCODE_CMP, instruction(block0, 1)->opcode);
334 EXPECT_EQ(ELK_CONDITIONAL_GE, instruction(block0, 1)->conditional_mod);
335 EXPECT_EQ(ELK_OPCODE_CMP, instruction(block0, 2)->opcode);
336 EXPECT_EQ(ELK_CONDITIONAL_GE, instruction(block0, 2)->conditional_mod);
337 }
338
TEST_F(cmod_propagation_vec4_test,intervening_flag_read)339 TEST_F(cmod_propagation_vec4_test, intervening_flag_read)
340 {
341 const vec4_builder bld = vec4_builder(v).at_end();
342 dst_reg dest0 = dst_reg(v, glsl_float_type());
343 dst_reg dest1 = dst_reg(v, glsl_float_type());
344 src_reg src0 = src_reg(v, glsl_float_type());
345 src_reg src1 = src_reg(v, glsl_float_type());
346 src_reg src2 = src_reg(v, glsl_float_type());
347 src_reg zero(elk_imm_f(0.0f));
348 bld.ADD(dest0, src0, src1);
349 set_predicate(ELK_PREDICATE_NORMAL, bld.SEL(dest1, src2, zero));
350 bld.CMP(bld.null_reg_f(), src_reg(dest0), zero, ELK_CONDITIONAL_GE);
351
352 /* = Before =
353 *
354 * 0: add dest0 src0 src1
355 * 1: (+f0) sel dest1 src2 0.0f
356 * 2: cmp.ge.f0 null dest0 0.0f
357 *
358 * = After =
359 * (no changes)
360 */
361
362 v->calculate_cfg();
363 elk_bblock_t *block0 = v->cfg->blocks[0];
364
365 EXPECT_EQ(0, block0->start_ip);
366 EXPECT_EQ(2, block0->end_ip);
367
368 EXPECT_FALSE(cmod_propagation(v));
369
370 ASSERT_EQ(0, block0->start_ip);
371 ASSERT_EQ(2, block0->end_ip);
372 EXPECT_EQ(ELK_OPCODE_ADD, instruction(block0, 0)->opcode);
373 EXPECT_EQ(ELK_OPCODE_SEL, instruction(block0, 1)->opcode);
374 EXPECT_EQ(ELK_PREDICATE_NORMAL, instruction(block0, 1)->predicate);
375 EXPECT_EQ(ELK_OPCODE_CMP, instruction(block0, 2)->opcode);
376 EXPECT_EQ(ELK_CONDITIONAL_GE, instruction(block0, 2)->conditional_mod);
377 }
378
TEST_F(cmod_propagation_vec4_test,intervening_dest_write)379 TEST_F(cmod_propagation_vec4_test, intervening_dest_write)
380 {
381 const vec4_builder bld = vec4_builder(v).at_end();
382 dst_reg dest = dst_reg(v, glsl_vec4_type());
383 src_reg src0 = src_reg(v, glsl_float_type());
384 src_reg src1 = src_reg(v, glsl_float_type());
385 src_reg src2 = src_reg(v, glsl_vec2_type());
386 src_reg zero(elk_imm_f(0.0f));
387 bld.ADD(offset(dest, 8, 2), src0, src1);
388 bld.emit(ELK_SHADER_OPCODE_TEX, dest, src2)
389 ->size_written = 4 * REG_SIZE;
390 bld.CMP(bld.null_reg_f(), offset(src_reg(dest), 8, 2), zero, ELK_CONDITIONAL_GE);
391
392 /* = Before =
393 *
394 * 0: add dest+2 src0 src1
395 * 1: tex rlen 4 dest+0 src2
396 * 2: cmp.ge.f0 null dest+2 0.0f
397 *
398 * = After =
399 * (no changes)
400 */
401
402 v->calculate_cfg();
403 elk_bblock_t *block0 = v->cfg->blocks[0];
404
405 EXPECT_EQ(0, block0->start_ip);
406 EXPECT_EQ(2, block0->end_ip);
407
408 EXPECT_FALSE(cmod_propagation(v));
409
410 ASSERT_EQ(0, block0->start_ip);
411 ASSERT_EQ(2, block0->end_ip);
412 EXPECT_EQ(ELK_OPCODE_ADD, instruction(block0, 0)->opcode);
413 EXPECT_EQ(ELK_CONDITIONAL_NONE, instruction(block0, 0)->conditional_mod);
414 EXPECT_EQ(ELK_SHADER_OPCODE_TEX, instruction(block0, 1)->opcode);
415 EXPECT_EQ(ELK_CONDITIONAL_NONE, instruction(block0, 0)->conditional_mod);
416 EXPECT_EQ(ELK_OPCODE_CMP, instruction(block0, 2)->opcode);
417 EXPECT_EQ(ELK_CONDITIONAL_GE, instruction(block0, 2)->conditional_mod);
418 }
419
TEST_F(cmod_propagation_vec4_test,intervening_flag_read_same_value)420 TEST_F(cmod_propagation_vec4_test, intervening_flag_read_same_value)
421 {
422 const vec4_builder bld = vec4_builder(v).at_end();
423 dst_reg dest0 = dst_reg(v, glsl_float_type());
424 dst_reg dest1 = dst_reg(v, glsl_float_type());
425 src_reg src0 = src_reg(v, glsl_float_type());
426 src_reg src1 = src_reg(v, glsl_float_type());
427 src_reg src2 = src_reg(v, glsl_float_type());
428 src_reg zero(elk_imm_f(0.0f));
429 dst_reg dest_null = bld.null_reg_f();
430 dest_null.writemask = WRITEMASK_X;
431
432 set_condmod(ELK_CONDITIONAL_GE, bld.ADD(dest0, src0, src1));
433 set_predicate(ELK_PREDICATE_NORMAL, bld.SEL(dest1, src2, zero));
434 bld.CMP(dest_null, src_reg(dest0), zero, ELK_CONDITIONAL_GE);
435
436 /* = Before =
437 *
438 * 0: add.ge.f0 dest0 src0 src1
439 * 1: (+f0) sel dest1 src2 0.0f
440 * 2: cmp.ge.f0 null.x dest0 0.0f
441 *
442 * = After =
443 * 0: add.ge.f0 dest0 src0 src1
444 * 1: (+f0) sel dest1 src2 0.0f
445 */
446
447 v->calculate_cfg();
448 elk_bblock_t *block0 = v->cfg->blocks[0];
449
450 EXPECT_EQ(0, block0->start_ip);
451 EXPECT_EQ(2, block0->end_ip);
452
453 EXPECT_TRUE(cmod_propagation(v));
454 ASSERT_EQ(0, block0->start_ip);
455 ASSERT_EQ(1, block0->end_ip);
456 EXPECT_EQ(ELK_OPCODE_ADD, instruction(block0, 0)->opcode);
457 EXPECT_EQ(ELK_CONDITIONAL_GE, instruction(block0, 0)->conditional_mod);
458 EXPECT_EQ(ELK_OPCODE_SEL, instruction(block0, 1)->opcode);
459 EXPECT_EQ(ELK_PREDICATE_NORMAL, instruction(block0, 1)->predicate);
460 }
461
TEST_F(cmod_propagation_vec4_test,negate)462 TEST_F(cmod_propagation_vec4_test, negate)
463 {
464 const vec4_builder bld = vec4_builder(v).at_end();
465 dst_reg dest = dst_reg(v, glsl_float_type());
466 src_reg src0 = src_reg(v, glsl_float_type());
467 src_reg src1 = src_reg(v, glsl_float_type());
468 src_reg zero(elk_imm_f(0.0f));
469 bld.ADD(dest, src0, src1);
470 src_reg tmp_src = src_reg(dest);
471 tmp_src.negate = true;
472 dst_reg dest_null = bld.null_reg_f();
473 dest_null.writemask = WRITEMASK_X;
474 bld.CMP(dest_null, tmp_src, zero, ELK_CONDITIONAL_GE);
475
476 /* = Before =
477 *
478 * 0: add dest src0 src1
479 * 1: cmp.ge.f0 null.x -dest 0.0f
480 *
481 * = After =
482 * 0: add.le.f0 dest src0 src1
483 */
484
485 v->calculate_cfg();
486 elk_bblock_t *block0 = v->cfg->blocks[0];
487
488 EXPECT_EQ(0, block0->start_ip);
489 EXPECT_EQ(1, block0->end_ip);
490
491 EXPECT_TRUE(cmod_propagation(v));
492 EXPECT_EQ(0, block0->start_ip);
493 EXPECT_EQ(0, block0->end_ip);
494 EXPECT_EQ(ELK_OPCODE_ADD, instruction(block0, 0)->opcode);
495 EXPECT_EQ(ELK_CONDITIONAL_LE, instruction(block0, 0)->conditional_mod);
496 }
497
TEST_F(cmod_propagation_vec4_test,movnz)498 TEST_F(cmod_propagation_vec4_test, movnz)
499 {
500 const vec4_builder bld = vec4_builder(v).at_end();
501 dst_reg dest = dst_reg(v, glsl_float_type());
502 src_reg src0 = src_reg(v, glsl_float_type());
503 src_reg src1 = src_reg(v, glsl_float_type());
504 dst_reg dest_null = bld.null_reg_f();
505 dest_null.writemask = WRITEMASK_X;
506
507 bld.CMP(dest, src0, src1, ELK_CONDITIONAL_L);
508 set_condmod(ELK_CONDITIONAL_NZ,
509 bld.MOV(dest_null, src_reg(dest)));
510
511 /* = Before =
512 *
513 * 0: cmp.l.f0 dest:F src0:F src1:F
514 * 1: mov.nz.f0 null.x dest:F
515 *
516 * = After =
517 * 0: cmp.l.f0 dest src0:F src1:F
518 */
519
520 v->calculate_cfg();
521 elk_bblock_t *block0 = v->cfg->blocks[0];
522
523 EXPECT_EQ(0, block0->start_ip);
524 EXPECT_EQ(1, block0->end_ip);
525
526 EXPECT_TRUE(cmod_propagation(v));
527
528 ASSERT_EQ(0, block0->start_ip);
529 ASSERT_EQ(0, block0->end_ip);
530 EXPECT_EQ(ELK_OPCODE_CMP, instruction(block0, 0)->opcode);
531 EXPECT_EQ(ELK_CONDITIONAL_L, instruction(block0, 0)->conditional_mod);
532 }
533
TEST_F(cmod_propagation_vec4_test,different_types_cmod_with_zero)534 TEST_F(cmod_propagation_vec4_test, different_types_cmod_with_zero)
535 {
536 const vec4_builder bld = vec4_builder(v).at_end();
537 dst_reg dest = dst_reg(v, glsl_int_type());
538 src_reg src0 = src_reg(v, glsl_int_type());
539 src_reg src1 = src_reg(v, glsl_int_type());
540 src_reg zero(elk_imm_f(0.0f));
541 bld.ADD(dest, src0, src1);
542 bld.CMP(bld.null_reg_f(), retype(src_reg(dest), ELK_REGISTER_TYPE_F), zero,
543 ELK_CONDITIONAL_GE);
544
545 /* = Before =
546 *
547 * 0: add dest:D src0:D src1:D
548 * 1: cmp.ge.f0 null:F dest:F 0.0f
549 *
550 * = After =
551 * (no changes)
552 */
553
554 v->calculate_cfg();
555 elk_bblock_t *block0 = v->cfg->blocks[0];
556
557 EXPECT_EQ(0, block0->start_ip);
558 EXPECT_EQ(1, block0->end_ip);
559
560 EXPECT_FALSE(cmod_propagation(v));
561
562 ASSERT_EQ(0, block0->start_ip);
563 ASSERT_EQ(1, block0->end_ip);
564 EXPECT_EQ(ELK_OPCODE_ADD, instruction(block0, 0)->opcode);
565 EXPECT_EQ(ELK_OPCODE_CMP, instruction(block0, 1)->opcode);
566 EXPECT_EQ(ELK_CONDITIONAL_GE, instruction(block0, 1)->conditional_mod);
567 }
568
TEST_F(cmod_propagation_vec4_test,andnz_non_one)569 TEST_F(cmod_propagation_vec4_test, andnz_non_one)
570 {
571 const vec4_builder bld = vec4_builder(v).at_end();
572 dst_reg dest = dst_reg(v, glsl_int_type());
573 src_reg src0 = src_reg(v, glsl_float_type());
574 src_reg zero(elk_imm_f(0.0f));
575 src_reg nonone(elk_imm_d(38));
576
577 bld.CMP(retype(dest, ELK_REGISTER_TYPE_F), src0, zero, ELK_CONDITIONAL_L);
578 set_condmod(ELK_CONDITIONAL_NZ,
579 bld.AND(bld.null_reg_d(), src_reg(dest), nonone));
580
581 /* = Before =
582 * 0: cmp.l.f0 dest:F src0:F 0F
583 * 1: and.nz.f0 null:D dest:D 38D
584 *
585 * = After =
586 * (no changes)
587 */
588
589 v->calculate_cfg();
590 elk_bblock_t *block0 = v->cfg->blocks[0];
591
592 EXPECT_EQ(0, block0->start_ip);
593 EXPECT_EQ(1, block0->end_ip);
594
595 EXPECT_FALSE(cmod_propagation(v));
596
597 ASSERT_EQ(0, block0->start_ip);
598 ASSERT_EQ(1, block0->end_ip);
599 EXPECT_EQ(ELK_OPCODE_CMP, instruction(block0, 0)->opcode);
600 EXPECT_EQ(ELK_CONDITIONAL_L, instruction(block0, 0)->conditional_mod);
601 EXPECT_EQ(ELK_OPCODE_AND, instruction(block0, 1)->opcode);
602 EXPECT_EQ(ELK_CONDITIONAL_NZ, instruction(block0, 1)->conditional_mod);
603 }
604
605 /* Note that basic is using glsl_type:float types, while this one is using
606 * glsl_type::vec4 */
TEST_F(cmod_propagation_vec4_test,basic_vec4)607 TEST_F(cmod_propagation_vec4_test, basic_vec4)
608 {
609 const vec4_builder bld = vec4_builder(v).at_end();
610 dst_reg dest = dst_reg(v, glsl_vec4_type());
611 src_reg src0 = src_reg(v, glsl_vec4_type());
612 src_reg src1 = src_reg(v, glsl_vec4_type());
613 src_reg zero(elk_imm_f(0.0f));
614
615 bld.MUL(dest, src0, src1);
616 bld.CMP(bld.null_reg_f(), src_reg(dest), zero, ELK_CONDITIONAL_NZ);
617
618 /* = Before =
619 * 0: mul dest.xyzw src0.xyzw src1.xyzw
620 * 1: cmp.nz.f0.0 null.xyzw dest.xyzw 0.0f
621 *
622 * = After =
623 * 0: mul.nz.f0.0 dest.xyzw src0.xyzw src1.xyzw
624 */
625
626 v->calculate_cfg();
627 elk_bblock_t *block0 = v->cfg->blocks[0];
628
629 EXPECT_EQ(0, block0->start_ip);
630 EXPECT_EQ(1, block0->end_ip);
631
632 EXPECT_TRUE(cmod_propagation(v));
633
634 ASSERT_EQ(0, block0->start_ip);
635 ASSERT_EQ(0, block0->end_ip);
636 EXPECT_EQ(ELK_OPCODE_MUL, instruction(block0, 0)->opcode);
637 EXPECT_EQ(ELK_CONDITIONAL_NZ, instruction(block0, 0)->conditional_mod);
638 }
639
TEST_F(cmod_propagation_vec4_test,basic_vec4_different_dst_writemask)640 TEST_F(cmod_propagation_vec4_test, basic_vec4_different_dst_writemask)
641 {
642 const vec4_builder bld = vec4_builder(v).at_end();
643 dst_reg dest = dst_reg(v, glsl_vec4_type());
644 dest.writemask = WRITEMASK_X;
645 src_reg src0 = src_reg(v, glsl_vec4_type());
646 src_reg src1 = src_reg(v, glsl_vec4_type());
647 src_reg zero(elk_imm_f(0.0f));
648 dst_reg dest_null = bld.null_reg_f();
649
650 bld.MUL(dest, src0, src1);
651 bld.CMP(dest_null, src_reg(dest), zero, ELK_CONDITIONAL_NZ);
652
653 /* = Before =
654 * 0: mul dest.x src0 src1
655 * 1: cmp.nz.f0.0 null dest 0.0f
656 *
657 * = After =
658 * (no changes)
659 */
660
661 v->calculate_cfg();
662 elk_bblock_t *block0 = v->cfg->blocks[0];
663
664 EXPECT_EQ(0, block0->start_ip);
665 EXPECT_EQ(1, block0->end_ip);
666
667 EXPECT_FALSE(cmod_propagation(v));
668
669 ASSERT_EQ(0, block0->start_ip);
670 ASSERT_EQ(1, block0->end_ip);
671 EXPECT_EQ(ELK_OPCODE_MUL, instruction(block0, 0)->opcode);
672 EXPECT_EQ(ELK_CONDITIONAL_NONE, instruction(block0, 0)->conditional_mod);
673 EXPECT_EQ(ELK_OPCODE_CMP, instruction(block0, 1)->opcode);
674 EXPECT_EQ(ELK_CONDITIONAL_NZ, instruction(block0, 1)->conditional_mod);
675 }
676
TEST_F(cmod_propagation_vec4_test,mad_one_component_vec4)677 TEST_F(cmod_propagation_vec4_test, mad_one_component_vec4)
678 {
679 const vec4_builder bld = vec4_builder(v).at_end();
680 dst_reg dest = dst_reg(v, glsl_vec4_type());
681 dest.writemask = WRITEMASK_X;
682 src_reg src0 = src_reg(v, glsl_vec4_type());
683 src_reg src1 = src_reg(v, glsl_vec4_type());
684 src_reg src2 = src_reg(v, glsl_vec4_type());
685 src0.swizzle = src1.swizzle = src2.swizzle = ELK_SWIZZLE_XXXX;
686 src2.negate = true;
687 src_reg zero(elk_imm_f(0.0f));
688 src_reg tmp(dest);
689 tmp.swizzle = ELK_SWIZZLE_XXXX;
690 dst_reg dest_null = bld.null_reg_f();
691 dest_null.writemask = WRITEMASK_X;
692
693 bld.MAD(dest, src0, src1, src2);
694 bld.CMP(dest_null, tmp, zero, ELK_CONDITIONAL_L);
695
696 /* = Before =
697 *
698 * 0: mad dest.x:F src0.xxxx:F src10.xxxx:F -src2.xxxx:F
699 * 1: cmp.l.f0.0 null.x:F dest.xxxx:F 0.0f
700 *
701 * = After =
702 * 0: mad.l.f0 dest.x:F src0.xxxx:F src10.xxxx:F -src2.xxxx:F
703 */
704
705 v->calculate_cfg();
706 elk_bblock_t *block0 = v->cfg->blocks[0];
707
708 EXPECT_EQ(0, block0->start_ip);
709 EXPECT_EQ(1, block0->end_ip);
710
711 EXPECT_TRUE(cmod_propagation(v));
712
713 ASSERT_EQ(0, block0->start_ip);
714 ASSERT_EQ(0, block0->end_ip);
715 EXPECT_EQ(ELK_OPCODE_MAD, instruction(block0, 0)->opcode);
716 EXPECT_EQ(ELK_CONDITIONAL_L, instruction(block0, 0)->conditional_mod);
717 }
718
TEST_F(cmod_propagation_vec4_test,mad_more_one_component_vec4)719 TEST_F(cmod_propagation_vec4_test, mad_more_one_component_vec4)
720 {
721 const vec4_builder bld = vec4_builder(v).at_end();
722 dst_reg dest = dst_reg(v, glsl_vec4_type());
723 dest.writemask = WRITEMASK_XW;
724 src_reg src0 = src_reg(v, glsl_vec4_type());
725 src_reg src1 = src_reg(v, glsl_vec4_type());
726 src_reg src2 = src_reg(v, glsl_vec4_type());
727 src0.swizzle = src1.swizzle = src2.swizzle = ELK_SWIZZLE_XXXX;
728 src2.negate = true;
729 src_reg zero(elk_imm_f(0.0f));
730 src_reg tmp(dest);
731 tmp.swizzle = ELK_SWIZZLE_XXXX;
732 dst_reg dest_null = bld.null_reg_f();
733
734 bld.MAD(dest, src0, src1, src2);
735 bld.CMP(dest_null, tmp, zero, ELK_CONDITIONAL_L);
736
737 /* = Before =
738 *
739 * 0: mad dest.xw:F src0.xxxx:F src10.xxxx:F -src2.xxxx:F
740 * 1: cmp.l.f0.0 null:F dest.xxxx:F zeroF
741 *
742 * = After =
743 * (No changes)
744 */
745
746 v->calculate_cfg();
747 elk_bblock_t *block0 = v->cfg->blocks[0];
748
749 EXPECT_EQ(0, block0->start_ip);
750 EXPECT_EQ(1, block0->end_ip);
751
752 EXPECT_FALSE(cmod_propagation(v));
753
754 ASSERT_EQ(0, block0->start_ip);
755 ASSERT_EQ(1, block0->end_ip);
756 EXPECT_EQ(ELK_OPCODE_MAD, instruction(block0, 0)->opcode);
757 EXPECT_EQ(ELK_CONDITIONAL_NONE, instruction(block0, 0)->conditional_mod);
758 EXPECT_EQ(ELK_OPCODE_CMP, instruction(block0, 1)->opcode);
759 EXPECT_EQ(ELK_CONDITIONAL_L, instruction(block0, 1)->conditional_mod);
760 }
761
TEST_F(cmod_propagation_vec4_test,cmp_mov_vec4)762 TEST_F(cmod_propagation_vec4_test, cmp_mov_vec4)
763 {
764 const vec4_builder bld = vec4_builder(v).at_end();
765 dst_reg dest = dst_reg(v, glsl_ivec4_type());
766 dest.writemask = WRITEMASK_X;
767 src_reg src0 = src_reg(v, glsl_ivec4_type());
768 src0.swizzle = ELK_SWIZZLE_XXXX;
769 src0.file = UNIFORM;
770 src_reg nonone = retype(elk_imm_d(16), ELK_REGISTER_TYPE_D);
771 src_reg mov_src = src_reg(dest);
772 mov_src.swizzle = ELK_SWIZZLE_XXXX;
773 dst_reg dest_null = bld.null_reg_d();
774 dest_null.writemask = WRITEMASK_X;
775
776 bld.CMP(dest, src0, nonone, ELK_CONDITIONAL_GE);
777 set_condmod(ELK_CONDITIONAL_NZ,
778 bld.MOV(dest_null, mov_src));
779
780 /* = Before =
781 *
782 * 0: cmp.ge.f0 dest.x:D u.xxxx:D 16D
783 * 1: mov.nz.f0 null.x:D dest.xxxx:D
784 *
785 * = After =
786 * 0: cmp.ge.f0 dest.x:D u.xxxx:D 16D
787 */
788
789 v->calculate_cfg();
790 elk_bblock_t *block0 = v->cfg->blocks[0];
791
792 EXPECT_EQ(0, block0->start_ip);
793 EXPECT_EQ(1, block0->end_ip);
794
795 EXPECT_TRUE(cmod_propagation(v));
796
797 ASSERT_EQ(0, block0->start_ip);
798 ASSERT_EQ(0, block0->end_ip);
799 EXPECT_EQ(ELK_OPCODE_CMP, instruction(block0, 0)->opcode);
800 EXPECT_EQ(ELK_CONDITIONAL_GE, instruction(block0, 0)->conditional_mod);
801 }
802
TEST_F(cmod_propagation_vec4_test,mul_cmp_different_channels_vec4)803 TEST_F(cmod_propagation_vec4_test, mul_cmp_different_channels_vec4)
804 {
805 const vec4_builder bld = vec4_builder(v).at_end();
806 dst_reg dest = dst_reg(v, glsl_vec4_type());
807 src_reg src0 = src_reg(v, glsl_vec4_type());
808 src_reg src1 = src_reg(v, glsl_vec4_type());
809 src_reg zero(elk_imm_f(0.0f));
810 src_reg cmp_src = src_reg(dest);
811 cmp_src.swizzle = ELK_SWIZZLE4(0,1,3,2);
812
813 bld.MUL(dest, src0, src1);
814 bld.CMP(bld.null_reg_f(), cmp_src, zero, ELK_CONDITIONAL_NZ);
815
816 /* = Before =
817 * 0: mul dest src0 src1
818 * 1: cmp.nz.f0.0 null dest.xywz 0.0f
819 *
820 * = After =
821 * (No changes)
822 */
823
824 v->calculate_cfg();
825 elk_bblock_t *block0 = v->cfg->blocks[0];
826
827 EXPECT_EQ(0, block0->start_ip);
828 EXPECT_EQ(1, block0->end_ip);
829
830 EXPECT_FALSE(cmod_propagation(v));
831
832 ASSERT_EQ(0, block0->start_ip);
833 ASSERT_EQ(1, block0->end_ip);
834 EXPECT_EQ(ELK_OPCODE_MUL, instruction(block0, 0)->opcode);
835 EXPECT_EQ(ELK_CONDITIONAL_NONE, instruction(block0, 0)->conditional_mod);
836 EXPECT_EQ(ELK_OPCODE_CMP, instruction(block0, 1)->opcode);
837 EXPECT_EQ(ELK_CONDITIONAL_NZ, instruction(block0, 1)->conditional_mod);
838 }
839
TEST_F(cmod_propagation_vec4_test,add_cmp_same_dst_writemask)840 TEST_F(cmod_propagation_vec4_test, add_cmp_same_dst_writemask)
841 {
842 const vec4_builder bld = vec4_builder(v).at_end();
843 dst_reg dest = dst_reg(v, glsl_vec4_type());
844 src_reg src0 = src_reg(v, glsl_vec4_type());
845 src_reg src1 = src_reg(v, glsl_vec4_type());
846 dst_reg dest_null = bld.null_reg_f();
847
848 bld.ADD(dest, src0, src1);
849 vec4_instruction *inst = bld.CMP(dest_null, src0, src1, ELK_CONDITIONAL_GE);
850 inst->src[1].negate = true;
851
852 /* = Before =
853 *
854 * 0: add dest.xyzw src0 src1
855 * 1: cmp.ge.f0 null.xyzw src0 -src1
856 *
857 * = After =
858 * 0: add.ge.f0 dest.xyzw src0 src1
859 */
860
861 v->calculate_cfg();
862 elk_bblock_t *block0 = v->cfg->blocks[0];
863
864 EXPECT_EQ(0, block0->start_ip);
865 EXPECT_EQ(1, block0->end_ip);
866
867 EXPECT_TRUE(cmod_propagation(v));
868
869 ASSERT_EQ(0, block0->start_ip);
870 ASSERT_EQ(0, block0->end_ip);
871 EXPECT_EQ(ELK_OPCODE_ADD, instruction(block0, 0)->opcode);
872 EXPECT_EQ(ELK_CONDITIONAL_GE, instruction(block0, 0)->conditional_mod);
873 }
874
TEST_F(cmod_propagation_vec4_test,add_cmp_different_dst_writemask)875 TEST_F(cmod_propagation_vec4_test, add_cmp_different_dst_writemask)
876 {
877 const vec4_builder bld = vec4_builder(v).at_end();
878 dst_reg dest = dst_reg(v, glsl_float_type());
879 src_reg src0 = src_reg(v, glsl_vec4_type());
880 src_reg src1 = src_reg(v, glsl_vec4_type());
881 dst_reg dest_null = bld.null_reg_f();
882
883 bld.ADD(dest, src0, src1);
884 vec4_instruction *inst = bld.CMP(dest_null, src0, src1, ELK_CONDITIONAL_GE);
885 inst->src[1].negate = true;
886
887 /* = Before =
888 *
889 * 0: add dest.x src0 src1
890 * 1: cmp.ge.f0 null.xyzw src0 -src1
891 *
892 * = After =
893 * (no changes)
894 */
895
896 v->calculate_cfg();
897 elk_bblock_t *block0 = v->cfg->blocks[0];
898
899 EXPECT_EQ(0, block0->start_ip);
900 EXPECT_EQ(1, block0->end_ip);
901
902 EXPECT_FALSE(cmod_propagation(v));
903
904 ASSERT_EQ(0, block0->start_ip);
905 ASSERT_EQ(1, block0->end_ip);
906 EXPECT_EQ(ELK_OPCODE_ADD, instruction(block0, 0)->opcode);
907 EXPECT_EQ(ELK_CONDITIONAL_NONE, instruction(block0, 0)->conditional_mod);
908 EXPECT_EQ(ELK_OPCODE_CMP, instruction(block0, 1)->opcode);
909 EXPECT_EQ(ELK_CONDITIONAL_GE, instruction(block0, 1)->conditional_mod);
910 }
911
TEST_F(cmod_propagation_vec4_test,prop_across_sel_gfx7)912 TEST_F(cmod_propagation_vec4_test, prop_across_sel_gfx7)
913 {
914 const vec4_builder bld = vec4_builder(v).at_end();
915 dst_reg dest1 = dst_reg(v, glsl_float_type());
916 dst_reg dest2 = dst_reg(v, glsl_float_type());
917 src_reg src0 = src_reg(v, glsl_float_type());
918 src_reg src1 = src_reg(v, glsl_float_type());
919 src_reg src2 = src_reg(v, glsl_float_type());
920 src_reg src3 = src_reg(v, glsl_float_type());
921 src_reg zero(elk_imm_f(0.0f));
922 dst_reg dest_null = bld.null_reg_f();
923 dest_null.writemask = WRITEMASK_X;
924
925 bld.ADD(dest1, src0, src1);
926 bld.SEL(dest2, src2, src3)
927 ->conditional_mod = ELK_CONDITIONAL_GE;
928 bld.CMP(dest_null, src_reg(dest1), zero, ELK_CONDITIONAL_GE);
929
930 /* = Before =
931 *
932 * 0: add dest1.x src0.xxxx src1.xxxx
933 * 1: sel.ge.f0 dest2.x src2.xxxx src3.xxxx
934 * 2: cmp.ge.f0 null.x dest.xxxx 0.0f
935 *
936 * = After =
937 * 0: add.ge.f0 dest.x src0.xxxx src1.xxxx
938 * 1: sel.ge.f0 dest2.x src2.xxxx src3.xxxx
939 */
940
941 v->calculate_cfg();
942 elk_bblock_t *block0 = v->cfg->blocks[0];
943
944 EXPECT_EQ(0, block0->start_ip);
945 EXPECT_EQ(2, block0->end_ip);
946
947 EXPECT_TRUE(cmod_propagation(v));
948
949 ASSERT_EQ(0, block0->start_ip);
950 ASSERT_EQ(1, block0->end_ip);
951 EXPECT_EQ(ELK_OPCODE_ADD, instruction(block0, 0)->opcode);
952 EXPECT_EQ(ELK_CONDITIONAL_GE, instruction(block0, 0)->conditional_mod);
953 EXPECT_EQ(ELK_OPCODE_SEL, instruction(block0, 1)->opcode);
954 EXPECT_EQ(ELK_CONDITIONAL_GE, instruction(block0, 1)->conditional_mod);
955 }
956
TEST_F(cmod_propagation_vec4_test,prop_across_sel_gfx5)957 TEST_F(cmod_propagation_vec4_test, prop_across_sel_gfx5)
958 {
959 devinfo->ver = 5;
960 devinfo->verx10 = devinfo->ver * 10;
961
962 const vec4_builder bld = vec4_builder(v).at_end();
963 dst_reg dest1 = dst_reg(v, glsl_float_type());
964 dst_reg dest2 = dst_reg(v, glsl_float_type());
965 src_reg src0 = src_reg(v, glsl_float_type());
966 src_reg src1 = src_reg(v, glsl_float_type());
967 src_reg src2 = src_reg(v, glsl_float_type());
968 src_reg src3 = src_reg(v, glsl_float_type());
969 src_reg zero(elk_imm_f(0.0f));
970 dst_reg dest_null = bld.null_reg_f();
971 dest_null.writemask = WRITEMASK_X;
972
973 bld.ADD(dest1, src0, src1);
974 bld.SEL(dest2, src2, src3)
975 ->conditional_mod = ELK_CONDITIONAL_GE;
976 bld.CMP(dest_null, src_reg(dest1), zero, ELK_CONDITIONAL_GE);
977
978 /* = Before =
979 *
980 * 0: add dest1.x src0.xxxx src1.xxxx
981 * 1: sel.ge.f0 dest2.x src2.xxxx src3.xxxx
982 * 2: cmp.ge.f0 null.x dest.xxxx 0.0f
983 *
984 * = After =
985 * (no changes)
986 *
987 * On Gfx4 and Gfx5, sel.l (for min) and sel.ge (for max) are implemented
988 * using a separate cmpn and sel instruction. This lowering occurs in
989 * fs_vistor::lower_minmax which is called a long time after the first
990 * calls to cmod_propagation.
991 */
992
993 v->calculate_cfg();
994 elk_bblock_t *block0 = v->cfg->blocks[0];
995
996 EXPECT_EQ(0, block0->start_ip);
997 EXPECT_EQ(2, block0->end_ip);
998
999 EXPECT_FALSE(cmod_propagation(v));
1000
1001 ASSERT_EQ(0, block0->start_ip);
1002 ASSERT_EQ(2, block0->end_ip);
1003 EXPECT_EQ(ELK_OPCODE_ADD, instruction(block0, 0)->opcode);
1004 EXPECT_EQ(ELK_CONDITIONAL_NONE, instruction(block0, 0)->conditional_mod);
1005 EXPECT_EQ(ELK_OPCODE_SEL, instruction(block0, 1)->opcode);
1006 EXPECT_EQ(ELK_CONDITIONAL_GE, instruction(block0, 1)->conditional_mod);
1007 EXPECT_EQ(ELK_OPCODE_CMP, instruction(block0, 2)->opcode);
1008 EXPECT_EQ(ELK_CONDITIONAL_GE, instruction(block0, 2)->conditional_mod);
1009 }
1010
TEST_F(cmod_propagation_vec4_test,prop_into_sel_gfx5)1011 TEST_F(cmod_propagation_vec4_test, prop_into_sel_gfx5)
1012 {
1013 devinfo->ver = 5;
1014 devinfo->verx10 = devinfo->ver * 10;
1015
1016 const vec4_builder bld = vec4_builder(v).at_end();
1017 dst_reg dest = dst_reg(v, glsl_float_type());
1018 src_reg src0 = src_reg(v, glsl_float_type());
1019 src_reg src1 = src_reg(v, glsl_float_type());
1020 src_reg zero(elk_imm_f(0.0f));
1021 dst_reg dest_null = bld.null_reg_f();
1022 dest_null.writemask = WRITEMASK_X;
1023
1024 bld.SEL(dest, src0, src1)
1025 ->conditional_mod = ELK_CONDITIONAL_GE;
1026 bld.CMP(dest_null, src_reg(dest), zero, ELK_CONDITIONAL_GE);
1027
1028 /* = Before =
1029 *
1030 * 0: sel.ge.f0 dest.x src2.xxxx src3.xxxx
1031 * 1: cmp.ge.f0 null.x dest.xxxx 0.0f
1032 *
1033 * = After =
1034 * (no changes)
1035 *
1036 * Do not copy propagate into a sel.cond instruction. While it does modify
1037 * the flags, the flags are not based on the result compared with zero (as
1038 * with most other instructions). The result is based on the sources
1039 * compared with each other (like cmp.cond).
1040 */
1041
1042 v->calculate_cfg();
1043 elk_bblock_t *block0 = v->cfg->blocks[0];
1044
1045 EXPECT_EQ(0, block0->start_ip);
1046 EXPECT_EQ(1, block0->end_ip);
1047
1048 EXPECT_FALSE(cmod_propagation(v));
1049
1050 ASSERT_EQ(0, block0->start_ip);
1051 ASSERT_EQ(1, block0->end_ip);
1052 EXPECT_EQ(ELK_OPCODE_SEL, instruction(block0, 0)->opcode);
1053 EXPECT_EQ(ELK_CONDITIONAL_GE, instruction(block0, 0)->conditional_mod);
1054 EXPECT_EQ(ELK_OPCODE_CMP, instruction(block0, 1)->opcode);
1055 EXPECT_EQ(ELK_CONDITIONAL_GE, instruction(block0, 1)->conditional_mod);
1056 }
1057