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