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