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 } 601