Home | History | Annotate | Download | only in i965
      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