i965: Move the back-end compiler to src/intel/compiler
[mesa.git] / src / intel / compiler / test_fs_saturate_propagation.cpp
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
24 #include <gtest/gtest.h>
25 #include "brw_fs.h"
26 #include "brw_cfg.h"
27 #include "program/program.h"
28
29 using namespace brw;
30
31 class saturate_propagation_test : public ::testing::Test {
32 virtual void SetUp();
33
34 public:
35 struct brw_compiler *compiler;
36 struct gen_device_info *devinfo;
37 struct gl_context *ctx;
38 struct brw_wm_prog_data *prog_data;
39 struct gl_shader_program *shader_prog;
40 fs_visitor *v;
41 };
42
43 class saturate_propagation_fs_visitor : public fs_visitor
44 {
45 public:
46 saturate_propagation_fs_visitor(struct brw_compiler *compiler,
47 struct brw_wm_prog_data *prog_data,
48 nir_shader *shader)
49 : fs_visitor(compiler, NULL, NULL, NULL,
50 &prog_data->base, (struct gl_program *) NULL,
51 shader, 8, -1) {}
52 };
53
54
55 void saturate_propagation_test::SetUp()
56 {
57 ctx = (struct gl_context *)calloc(1, sizeof(*ctx));
58 compiler = (struct brw_compiler *)calloc(1, sizeof(*compiler));
59 devinfo = (struct gen_device_info *)calloc(1, sizeof(*devinfo));
60 compiler->devinfo = devinfo;
61
62 prog_data = ralloc(NULL, struct brw_wm_prog_data);
63 nir_shader *shader =
64 nir_shader_create(NULL, MESA_SHADER_FRAGMENT, NULL, NULL);
65
66 v = new saturate_propagation_fs_visitor(compiler, prog_data, shader);
67
68 devinfo->gen = 4;
69 }
70
71 static fs_inst *
72 instruction(bblock_t *block, int num)
73 {
74 fs_inst *inst = (fs_inst *)block->start();
75 for (int i = 0; i < num; i++) {
76 inst = (fs_inst *)inst->next;
77 }
78 return inst;
79 }
80
81 static bool
82 saturate_propagation(fs_visitor *v)
83 {
84 const bool print = false;
85
86 if (print) {
87 fprintf(stderr, "= Before =\n");
88 v->cfg->dump(v);
89 }
90
91 bool ret = v->opt_saturate_propagation();
92
93 if (print) {
94 fprintf(stderr, "\n= After =\n");
95 v->cfg->dump(v);
96 }
97
98 return ret;
99 }
100
101 TEST_F(saturate_propagation_test, basic)
102 {
103 const fs_builder &bld = v->bld;
104 fs_reg dst0 = v->vgrf(glsl_type::float_type);
105 fs_reg dst1 = v->vgrf(glsl_type::float_type);
106 fs_reg src0 = v->vgrf(glsl_type::float_type);
107 fs_reg src1 = v->vgrf(glsl_type::float_type);
108 bld.ADD(dst0, src0, src1);
109 set_saturate(true, bld.MOV(dst1, dst0));
110
111 /* = Before =
112 *
113 * 0: add(8) dst0 src0 src1
114 * 1: mov.sat(8) dst1 dst0
115 *
116 * = After =
117 * 0: add.sat(8) dst0 src0 src1
118 * 1: mov(8) dst1 dst0
119 */
120
121 v->calculate_cfg();
122 bblock_t *block0 = v->cfg->blocks[0];
123
124 EXPECT_EQ(0, block0->start_ip);
125 EXPECT_EQ(1, block0->end_ip);
126
127 EXPECT_TRUE(saturate_propagation(v));
128 EXPECT_EQ(0, block0->start_ip);
129 EXPECT_EQ(1, block0->end_ip);
130 EXPECT_EQ(BRW_OPCODE_ADD, instruction(block0, 0)->opcode);
131 EXPECT_TRUE(instruction(block0, 0)->saturate);
132 EXPECT_EQ(BRW_OPCODE_MOV, instruction(block0, 1)->opcode);
133 EXPECT_FALSE(instruction(block0, 1)->saturate);
134 }
135
136 TEST_F(saturate_propagation_test, other_non_saturated_use)
137 {
138 const fs_builder &bld = v->bld;
139 fs_reg dst0 = v->vgrf(glsl_type::float_type);
140 fs_reg dst1 = v->vgrf(glsl_type::float_type);
141 fs_reg dst2 = v->vgrf(glsl_type::float_type);
142 fs_reg src0 = v->vgrf(glsl_type::float_type);
143 fs_reg src1 = v->vgrf(glsl_type::float_type);
144 bld.ADD(dst0, src0, src1);
145 set_saturate(true, bld.MOV(dst1, dst0));
146 bld.ADD(dst2, dst0, src0);
147
148 /* = Before =
149 *
150 * 0: add(8) dst0 src0 src1
151 * 1: mov.sat(8) dst1 dst0
152 * 2: add(8) dst2 dst0 src0
153 *
154 * = After =
155 * (no changes)
156 */
157
158 v->calculate_cfg();
159 bblock_t *block0 = v->cfg->blocks[0];
160
161 EXPECT_EQ(0, block0->start_ip);
162 EXPECT_EQ(2, block0->end_ip);
163
164 EXPECT_FALSE(saturate_propagation(v));
165 EXPECT_EQ(0, block0->start_ip);
166 EXPECT_EQ(2, block0->end_ip);
167 EXPECT_EQ(BRW_OPCODE_ADD, instruction(block0, 0)->opcode);
168 EXPECT_FALSE(instruction(block0, 0)->saturate);
169 EXPECT_EQ(BRW_OPCODE_MOV, instruction(block0, 1)->opcode);
170 EXPECT_TRUE(instruction(block0, 1)->saturate);
171 EXPECT_EQ(BRW_OPCODE_ADD, instruction(block0, 2)->opcode);
172 }
173
174 TEST_F(saturate_propagation_test, predicated_instruction)
175 {
176 const fs_builder &bld = v->bld;
177 fs_reg dst0 = v->vgrf(glsl_type::float_type);
178 fs_reg dst1 = v->vgrf(glsl_type::float_type);
179 fs_reg src0 = v->vgrf(glsl_type::float_type);
180 fs_reg src1 = v->vgrf(glsl_type::float_type);
181 bld.ADD(dst0, src0, src1)
182 ->predicate = BRW_PREDICATE_NORMAL;
183 set_saturate(true, bld.MOV(dst1, dst0));
184
185 /* = Before =
186 *
187 * 0: (+f0) add(8) dst0 src0 src1
188 * 1: mov.sat(8) dst1 dst0
189 *
190 * = After =
191 * (no changes)
192 */
193
194 v->calculate_cfg();
195 bblock_t *block0 = v->cfg->blocks[0];
196
197 EXPECT_EQ(0, block0->start_ip);
198 EXPECT_EQ(1, block0->end_ip);
199
200 EXPECT_FALSE(saturate_propagation(v));
201 EXPECT_EQ(0, block0->start_ip);
202 EXPECT_EQ(1, block0->end_ip);
203 EXPECT_EQ(BRW_OPCODE_ADD, instruction(block0, 0)->opcode);
204 EXPECT_FALSE(instruction(block0, 0)->saturate);
205 EXPECT_EQ(BRW_OPCODE_MOV, instruction(block0, 1)->opcode);
206 EXPECT_TRUE(instruction(block0, 1)->saturate);
207 }
208
209 TEST_F(saturate_propagation_test, neg_mov_sat)
210 {
211 const fs_builder &bld = v->bld;
212 fs_reg dst0 = v->vgrf(glsl_type::float_type);
213 fs_reg dst1 = v->vgrf(glsl_type::float_type);
214 fs_reg src0 = v->vgrf(glsl_type::float_type);
215 bld.RNDU(dst0, src0);
216 dst0.negate = true;
217 set_saturate(true, bld.MOV(dst1, dst0));
218
219 /* = Before =
220 *
221 * 0: rndu(8) dst0 src0
222 * 1: mov.sat(8) dst1 -dst0
223 *
224 * = After =
225 * (no changes)
226 */
227
228 v->calculate_cfg();
229 bblock_t *block0 = v->cfg->blocks[0];
230
231 EXPECT_EQ(0, block0->start_ip);
232 EXPECT_EQ(1, block0->end_ip);
233
234 EXPECT_FALSE(saturate_propagation(v));
235 EXPECT_EQ(0, block0->start_ip);
236 EXPECT_EQ(1, block0->end_ip);
237 EXPECT_EQ(BRW_OPCODE_RNDU, instruction(block0, 0)->opcode);
238 EXPECT_FALSE(instruction(block0, 0)->saturate);
239 EXPECT_EQ(BRW_OPCODE_MOV, instruction(block0, 1)->opcode);
240 EXPECT_TRUE(instruction(block0, 1)->saturate);
241 }
242
243 TEST_F(saturate_propagation_test, add_neg_mov_sat)
244 {
245 const fs_builder &bld = v->bld;
246 fs_reg dst0 = v->vgrf(glsl_type::float_type);
247 fs_reg dst1 = v->vgrf(glsl_type::float_type);
248 fs_reg src0 = v->vgrf(glsl_type::float_type);
249 fs_reg src1 = v->vgrf(glsl_type::float_type);
250 bld.ADD(dst0, src0, src1);
251 dst0.negate = true;
252 set_saturate(true, bld.MOV(dst1, dst0));
253
254 /* = Before =
255 *
256 * 0: add(8) dst0 src0 src1
257 * 1: mov.sat(8) dst1 -dst0
258 *
259 * = After =
260 * 0: add.sat(8) dst0 -src0 -src1
261 * 1: mov(8) dst1 dst0
262 */
263
264 v->calculate_cfg();
265 bblock_t *block0 = v->cfg->blocks[0];
266
267 EXPECT_EQ(0, block0->start_ip);
268 EXPECT_EQ(1, block0->end_ip);
269
270 EXPECT_TRUE(saturate_propagation(v));
271 EXPECT_EQ(0, block0->start_ip);
272 EXPECT_EQ(1, block0->end_ip);
273 EXPECT_EQ(BRW_OPCODE_ADD, instruction(block0, 0)->opcode);
274 EXPECT_TRUE(instruction(block0, 0)->saturate);
275 EXPECT_TRUE(instruction(block0, 0)->src[0].negate);
276 EXPECT_TRUE(instruction(block0, 0)->src[1].negate);
277 EXPECT_EQ(BRW_OPCODE_MOV, instruction(block0, 1)->opcode);
278 EXPECT_FALSE(instruction(block0, 1)->saturate);
279 }
280
281 TEST_F(saturate_propagation_test, mul_neg_mov_sat)
282 {
283 const fs_builder &bld = v->bld;
284 fs_reg dst0 = v->vgrf(glsl_type::float_type);
285 fs_reg dst1 = v->vgrf(glsl_type::float_type);
286 fs_reg src0 = v->vgrf(glsl_type::float_type);
287 fs_reg src1 = v->vgrf(glsl_type::float_type);
288 bld.MUL(dst0, src0, src1);
289 dst0.negate = true;
290 set_saturate(true, bld.MOV(dst1, dst0));
291
292 /* = Before =
293 *
294 * 0: mul(8) dst0 src0 src1
295 * 1: mov.sat(8) dst1 -dst0
296 *
297 * = After =
298 * 0: mul.sat(8) dst0 src0 -src1
299 * 1: mov(8) dst1 dst0
300 */
301
302 v->calculate_cfg();
303 bblock_t *block0 = v->cfg->blocks[0];
304
305 EXPECT_EQ(0, block0->start_ip);
306 EXPECT_EQ(1, block0->end_ip);
307
308 EXPECT_TRUE(saturate_propagation(v));
309 EXPECT_EQ(0, block0->start_ip);
310 EXPECT_EQ(1, block0->end_ip);
311 EXPECT_EQ(BRW_OPCODE_MUL, instruction(block0, 0)->opcode);
312 EXPECT_TRUE(instruction(block0, 0)->saturate);
313 EXPECT_TRUE(instruction(block0, 0)->src[0].negate);
314 EXPECT_EQ(BRW_OPCODE_MOV, instruction(block0, 1)->opcode);
315 EXPECT_FALSE(instruction(block0, 1)->saturate);
316 EXPECT_FALSE(instruction(block0, 1)->src[0].negate);
317 }
318
319 TEST_F(saturate_propagation_test, mul_mov_sat_neg_mov_sat)
320 {
321 const fs_builder &bld = v->bld;
322 fs_reg dst0 = v->vgrf(glsl_type::float_type);
323 fs_reg dst1 = v->vgrf(glsl_type::float_type);
324 fs_reg dst2 = v->vgrf(glsl_type::float_type);
325 fs_reg src0 = v->vgrf(glsl_type::float_type);
326 fs_reg src1 = v->vgrf(glsl_type::float_type);
327 bld.MUL(dst0, src0, src1);
328 set_saturate(true, bld.MOV(dst1, dst0));
329 dst0.negate = true;
330 set_saturate(true, bld.MOV(dst2, dst0));
331
332 /* = Before =
333 *
334 * 0: mul(8) dst0 src0 src1
335 * 1: mov.sat(8) dst1 dst0
336 * 2: mov.sat(8) dst2 -dst0
337 *
338 * = After =
339 * (no changes)
340 */
341
342 v->calculate_cfg();
343 bblock_t *block0 = v->cfg->blocks[0];
344
345 EXPECT_EQ(0, block0->start_ip);
346 EXPECT_EQ(2, block0->end_ip);
347
348 EXPECT_FALSE(saturate_propagation(v));
349 EXPECT_EQ(0, block0->start_ip);
350 EXPECT_EQ(2, block0->end_ip);
351 EXPECT_EQ(BRW_OPCODE_MUL, instruction(block0, 0)->opcode);
352 EXPECT_FALSE(instruction(block0, 0)->saturate);
353 EXPECT_FALSE(instruction(block0, 0)->src[1].negate);
354 EXPECT_EQ(BRW_OPCODE_MOV, instruction(block0, 1)->opcode);
355 EXPECT_TRUE(instruction(block0, 1)->saturate);
356 EXPECT_EQ(BRW_OPCODE_MOV, instruction(block0, 2)->opcode);
357 EXPECT_TRUE(instruction(block0, 2)->src[0].negate);
358 EXPECT_TRUE(instruction(block0, 2)->saturate);
359 }
360
361 TEST_F(saturate_propagation_test, mul_neg_mov_sat_neg_mov_sat)
362 {
363 const fs_builder &bld = v->bld;
364 fs_reg dst0 = v->vgrf(glsl_type::float_type);
365 fs_reg dst1 = v->vgrf(glsl_type::float_type);
366 fs_reg dst2 = v->vgrf(glsl_type::float_type);
367 fs_reg src0 = v->vgrf(glsl_type::float_type);
368 fs_reg src1 = v->vgrf(glsl_type::float_type);
369 bld.MUL(dst0, src0, src1);
370 dst0.negate = true;
371 set_saturate(true, bld.MOV(dst1, dst0));
372 set_saturate(true, bld.MOV(dst2, dst0));
373
374 /* = Before =
375 *
376 * 0: mul(8) dst0 src0 src1
377 * 1: mov.sat(8) dst1 -dst0
378 * 2: mov.sat(8) dst2 -dst0
379 *
380 * = After =
381 * (no changes)
382 */
383
384 v->calculate_cfg();
385 bblock_t *block0 = v->cfg->blocks[0];
386
387 EXPECT_EQ(0, block0->start_ip);
388 EXPECT_EQ(2, block0->end_ip);
389
390 EXPECT_FALSE(saturate_propagation(v));
391 EXPECT_EQ(0, block0->start_ip);
392 EXPECT_EQ(2, block0->end_ip);
393 EXPECT_EQ(BRW_OPCODE_MUL, instruction(block0, 0)->opcode);
394 EXPECT_FALSE(instruction(block0, 0)->saturate);
395 EXPECT_FALSE(instruction(block0, 0)->src[1].negate);
396 EXPECT_EQ(BRW_OPCODE_MOV, instruction(block0, 1)->opcode);
397 EXPECT_TRUE(instruction(block0, 1)->src[0].negate);
398 EXPECT_TRUE(instruction(block0, 1)->saturate);
399 EXPECT_EQ(BRW_OPCODE_MOV, instruction(block0, 2)->opcode);
400 EXPECT_TRUE(instruction(block0, 2)->src[0].negate);
401 EXPECT_TRUE(instruction(block0, 2)->saturate);
402 }
403
404 TEST_F(saturate_propagation_test, abs_mov_sat)
405 {
406 const fs_builder &bld = v->bld;
407 fs_reg dst0 = v->vgrf(glsl_type::float_type);
408 fs_reg dst1 = v->vgrf(glsl_type::float_type);
409 fs_reg src0 = v->vgrf(glsl_type::float_type);
410 fs_reg src1 = v->vgrf(glsl_type::float_type);
411 bld.ADD(dst0, src0, src1);
412 dst0.abs = true;
413 set_saturate(true, bld.MOV(dst1, dst0));
414
415 /* = Before =
416 *
417 * 0: add(8) dst0 src0 src1
418 * 1: mov.sat(8) dst1 (abs)dst0
419 *
420 * = After =
421 * (no changes)
422 */
423
424 v->calculate_cfg();
425 bblock_t *block0 = v->cfg->blocks[0];
426
427 EXPECT_EQ(0, block0->start_ip);
428 EXPECT_EQ(1, block0->end_ip);
429
430 EXPECT_FALSE(saturate_propagation(v));
431 EXPECT_EQ(0, block0->start_ip);
432 EXPECT_EQ(1, block0->end_ip);
433 EXPECT_EQ(BRW_OPCODE_ADD, instruction(block0, 0)->opcode);
434 EXPECT_FALSE(instruction(block0, 0)->saturate);
435 EXPECT_EQ(BRW_OPCODE_MOV, instruction(block0, 1)->opcode);
436 EXPECT_TRUE(instruction(block0, 1)->saturate);
437 }
438
439 TEST_F(saturate_propagation_test, producer_saturates)
440 {
441 const fs_builder &bld = v->bld;
442 fs_reg dst0 = v->vgrf(glsl_type::float_type);
443 fs_reg dst1 = v->vgrf(glsl_type::float_type);
444 fs_reg dst2 = v->vgrf(glsl_type::float_type);
445 fs_reg src0 = v->vgrf(glsl_type::float_type);
446 fs_reg src1 = v->vgrf(glsl_type::float_type);
447 set_saturate(true, bld.ADD(dst0, src0, src1));
448 set_saturate(true, bld.MOV(dst1, dst0));
449 bld.MOV(dst2, dst0);
450
451 /* = Before =
452 *
453 * 0: add.sat(8) dst0 src0 src1
454 * 1: mov.sat(8) dst1 dst0
455 * 2: mov(8) dst2 dst0
456 *
457 * = After =
458 * 0: add.sat(8) dst0 src0 src1
459 * 1: mov(8) dst1 dst0
460 * 2: mov(8) dst2 dst0
461 */
462
463 v->calculate_cfg();
464 bblock_t *block0 = v->cfg->blocks[0];
465
466 EXPECT_EQ(0, block0->start_ip);
467 EXPECT_EQ(2, block0->end_ip);
468
469 EXPECT_TRUE(saturate_propagation(v));
470 EXPECT_EQ(0, block0->start_ip);
471 EXPECT_EQ(2, block0->end_ip);
472 EXPECT_EQ(BRW_OPCODE_ADD, instruction(block0, 0)->opcode);
473 EXPECT_TRUE(instruction(block0, 0)->saturate);
474 EXPECT_EQ(BRW_OPCODE_MOV, instruction(block0, 1)->opcode);
475 EXPECT_FALSE(instruction(block0, 1)->saturate);
476 }
477
478 TEST_F(saturate_propagation_test, intervening_saturating_copy)
479 {
480 const fs_builder &bld = v->bld;
481 fs_reg dst0 = v->vgrf(glsl_type::float_type);
482 fs_reg dst1 = v->vgrf(glsl_type::float_type);
483 fs_reg dst2 = v->vgrf(glsl_type::float_type);
484 fs_reg src0 = v->vgrf(glsl_type::float_type);
485 fs_reg src1 = v->vgrf(glsl_type::float_type);
486 bld.ADD(dst0, src0, src1);
487 set_saturate(true, bld.MOV(dst1, dst0));
488 set_saturate(true, bld.MOV(dst2, dst0));
489
490 /* = Before =
491 *
492 * 0: add(8) dst0 src0 src1
493 * 1: mov.sat(8) dst1 dst0
494 * 2: mov.sat(8) dst2 dst0
495 *
496 * = After =
497 * 0: add.sat(8) dst0 src0 src1
498 * 1: mov(8) dst1 dst0
499 * 2: mov(8) dst2 dst0
500 */
501
502 v->calculate_cfg();
503 bblock_t *block0 = v->cfg->blocks[0];
504
505 EXPECT_EQ(0, block0->start_ip);
506 EXPECT_EQ(2, block0->end_ip);
507
508 EXPECT_TRUE(saturate_propagation(v));
509 EXPECT_EQ(0, block0->start_ip);
510 EXPECT_EQ(2, block0->end_ip);
511 EXPECT_EQ(BRW_OPCODE_ADD, instruction(block0, 0)->opcode);
512 EXPECT_TRUE(instruction(block0, 0)->saturate);
513 EXPECT_EQ(BRW_OPCODE_MOV, instruction(block0, 1)->opcode);
514 EXPECT_FALSE(instruction(block0, 1)->saturate);
515 EXPECT_EQ(BRW_OPCODE_MOV, instruction(block0, 2)->opcode);
516 EXPECT_FALSE(instruction(block0, 2)->saturate);
517 }
518
519 TEST_F(saturate_propagation_test, intervening_dest_write)
520 {
521 const fs_builder &bld = v->bld;
522 fs_reg dst0 = v->vgrf(glsl_type::vec4_type);
523 fs_reg dst1 = v->vgrf(glsl_type::float_type);
524 fs_reg src0 = v->vgrf(glsl_type::float_type);
525 fs_reg src1 = v->vgrf(glsl_type::float_type);
526 fs_reg src2 = v->vgrf(glsl_type::vec2_type);
527 bld.ADD(offset(dst0, bld, 2), src0, src1);
528 bld.emit(SHADER_OPCODE_TEX, dst0, src2)
529 ->size_written = 4 * REG_SIZE;
530 set_saturate(true, bld.MOV(dst1, offset(dst0, bld, 2)));
531
532 /* = Before =
533 *
534 * 0: add(8) dst0+2 src0 src1
535 * 1: tex(8) rlen 4 dst0+0 src2
536 * 2: mov.sat(8) dst1 dst0+2
537 *
538 * = After =
539 * (no changes)
540 */
541
542 v->calculate_cfg();
543 bblock_t *block0 = v->cfg->blocks[0];
544
545 EXPECT_EQ(0, block0->start_ip);
546 EXPECT_EQ(2, block0->end_ip);
547
548 EXPECT_FALSE(saturate_propagation(v));
549 EXPECT_EQ(0, block0->start_ip);
550 EXPECT_EQ(2, block0->end_ip);
551 EXPECT_EQ(BRW_OPCODE_ADD, instruction(block0, 0)->opcode);
552 EXPECT_FALSE(instruction(block0, 0)->saturate);
553 EXPECT_EQ(SHADER_OPCODE_TEX, instruction(block0, 1)->opcode);
554 EXPECT_FALSE(instruction(block0, 0)->saturate);
555 EXPECT_EQ(BRW_OPCODE_MOV, instruction(block0, 2)->opcode);
556 EXPECT_TRUE(instruction(block0, 2)->saturate);
557 }
558
559 TEST_F(saturate_propagation_test, mul_neg_mov_sat_mov_sat)
560 {
561 const fs_builder &bld = v->bld;
562 fs_reg dst0 = v->vgrf(glsl_type::float_type);
563 fs_reg dst1 = v->vgrf(glsl_type::float_type);
564 fs_reg dst2 = v->vgrf(glsl_type::float_type);
565 fs_reg src0 = v->vgrf(glsl_type::float_type);
566 fs_reg src1 = v->vgrf(glsl_type::float_type);
567 bld.MUL(dst0, src0, src1);
568 dst0.negate = true;
569 set_saturate(true, bld.MOV(dst1, dst0));
570 dst0.negate = false;
571 set_saturate(true, bld.MOV(dst2, dst0));
572
573 /* = Before =
574 *
575 * 0: mul(8) dst0 src0 src1
576 * 1: mov.sat(8) dst1 -dst0
577 * 2: mov.sat(8) dst2 dst0
578 *
579 * = After =
580 * (no changes)
581 */
582
583 v->calculate_cfg();
584 bblock_t *block0 = v->cfg->blocks[0];
585
586 EXPECT_EQ(0, block0->start_ip);
587 EXPECT_EQ(2, block0->end_ip);
588
589 EXPECT_FALSE(saturate_propagation(v));
590 EXPECT_EQ(0, block0->start_ip);
591 EXPECT_EQ(2, block0->end_ip);
592 EXPECT_EQ(BRW_OPCODE_MUL, instruction(block0, 0)->opcode);
593 EXPECT_FALSE(instruction(block0, 0)->saturate);
594 EXPECT_FALSE(instruction(block0, 0)->src[1].negate);
595 EXPECT_EQ(BRW_OPCODE_MOV, instruction(block0, 1)->opcode);
596 EXPECT_TRUE(instruction(block0, 1)->saturate);
597 EXPECT_TRUE(instruction(block0, 1)->src[0].negate);
598 EXPECT_EQ(BRW_OPCODE_MOV, instruction(block0, 2)->opcode);
599 EXPECT_TRUE(instruction(block0, 2)->saturate);
600 }