• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright © 2016 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
21  * DEALINGS IN THE SOFTWARE.
22  */
23 #include <gtest/gtest.h>
24 #include "ir.h"
25 #include "ir_builder.h"
26 #include "opt_add_neg_to_sub.h"
27 
28 using namespace ir_builder;
29 
30 class add_neg_to_sub : public ::testing::Test {
31 public:
32    virtual void SetUp();
33    virtual void TearDown();
34 
35    exec_list instructions;
36    ir_factory *body;
37    void *mem_ctx;
38    ir_variable *var_a;
39    ir_variable *var_b;
40    ir_variable *var_c;
41    add_neg_to_sub_visitor v;
42 };
43 
44 void
SetUp()45 add_neg_to_sub::SetUp()
46 {
47    mem_ctx = ralloc_context(NULL);
48 
49    instructions.make_empty();
50    body = new ir_factory(&instructions, mem_ctx);
51 
52    var_a = new(mem_ctx) ir_variable(glsl_type::float_type,
53                                     "a",
54                                     ir_var_temporary);
55 
56    var_b = new(mem_ctx) ir_variable(glsl_type::float_type,
57                                     "b",
58                                     ir_var_temporary);
59 
60    var_c = new(mem_ctx) ir_variable(glsl_type::float_type,
61                                     "c",
62                                     ir_var_temporary);
63 }
64 
65 void
TearDown()66 add_neg_to_sub::TearDown()
67 {
68    delete body;
69    body = NULL;
70 
71    ralloc_free(mem_ctx);
72    mem_ctx = NULL;
73 }
74 
TEST_F(add_neg_to_sub,a_plus_b)75 TEST_F(add_neg_to_sub, a_plus_b)
76 {
77    body->emit(assign(var_c, add(var_a, var_b)));
78 
79    visit_list_elements(&v, &instructions);
80 
81    ASSERT_FALSE(instructions.is_empty());
82 
83    ir_instruction *const ir = (ir_instruction *) instructions.pop_head();
84 
85    EXPECT_TRUE(instructions.is_empty());
86 
87    /* The resulting instruction should be 'c = a + b'. */
88    ir_assignment *const assign = ir->as_assignment();
89    ASSERT_NE((void *)0, assign);
90 
91    EXPECT_EQ(var_c, assign->lhs->variable_referenced());
92 
93    ir_expression *const expr = assign->rhs->as_expression();
94    ASSERT_NE((void *)0, expr);
95    EXPECT_EQ(ir_binop_add, expr->operation);
96 
97    ir_dereference_variable *const deref_a =
98       expr->operands[0]->as_dereference_variable();
99    ir_dereference_variable *const deref_b =
100       expr->operands[1]->as_dereference_variable();
101 
102    ASSERT_NE((void *)0, deref_a);
103    EXPECT_EQ(var_a, deref_a->var);
104    ASSERT_NE((void *)0, deref_b);
105    EXPECT_EQ(var_b, deref_b->var);
106 }
107 
TEST_F(add_neg_to_sub,a_plus_neg_b)108 TEST_F(add_neg_to_sub, a_plus_neg_b)
109 {
110    body->emit(assign(var_c, add(var_a, neg(var_b))));
111 
112    visit_list_elements(&v, &instructions);
113 
114    ASSERT_FALSE(instructions.is_empty());
115 
116    ir_instruction *const ir = (ir_instruction *) instructions.pop_head();
117 
118    EXPECT_TRUE(instructions.is_empty());
119 
120    /* The resulting instruction should be 'c = a - b'. */
121    ir_assignment *const assign = ir->as_assignment();
122    ASSERT_NE((void *)0, assign);
123 
124    EXPECT_EQ(var_c, assign->lhs->variable_referenced());
125 
126    ir_expression *const expr = assign->rhs->as_expression();
127    ASSERT_NE((void *)0, expr);
128    EXPECT_EQ(ir_binop_sub, expr->operation);
129 
130    ir_dereference_variable *const deref_a =
131       expr->operands[0]->as_dereference_variable();
132    ir_dereference_variable *const deref_b =
133       expr->operands[1]->as_dereference_variable();
134 
135    ASSERT_NE((void *)0, deref_a);
136    EXPECT_EQ(var_a, deref_a->var);
137    ASSERT_NE((void *)0, deref_b);
138    EXPECT_EQ(var_b, deref_b->var);
139 }
140 
TEST_F(add_neg_to_sub,neg_a_plus_b)141 TEST_F(add_neg_to_sub, neg_a_plus_b)
142 {
143    body->emit(assign(var_c, add(neg(var_a), var_b)));
144 
145    visit_list_elements(&v, &instructions);
146 
147    ASSERT_FALSE(instructions.is_empty());
148 
149    ir_instruction *const ir = (ir_instruction *) instructions.pop_head();
150 
151    EXPECT_TRUE(instructions.is_empty());
152 
153    /* The resulting instruction should be 'c = b - a'. */
154    ir_assignment *const assign = ir->as_assignment();
155    ASSERT_NE((void *)0, assign);
156 
157    EXPECT_EQ(var_c, assign->lhs->variable_referenced());
158 
159    ir_expression *const expr = assign->rhs->as_expression();
160    ASSERT_NE((void *)0, expr);
161    EXPECT_EQ(ir_binop_sub, expr->operation);
162 
163    ir_dereference_variable *const deref_b =
164       expr->operands[0]->as_dereference_variable();
165    ir_dereference_variable *const deref_a =
166       expr->operands[1]->as_dereference_variable();
167 
168    ASSERT_NE((void *)0, deref_a);
169    EXPECT_EQ(var_a, deref_a->var);
170    ASSERT_NE((void *)0, deref_b);
171    EXPECT_EQ(var_b, deref_b->var);
172 }
173 
TEST_F(add_neg_to_sub,neg_a_plus_neg_b)174 TEST_F(add_neg_to_sub, neg_a_plus_neg_b)
175 {
176    body->emit(assign(var_c, add(neg(var_a), neg(var_b))));
177 
178    visit_list_elements(&v, &instructions);
179 
180    ASSERT_FALSE(instructions.is_empty());
181 
182    ir_instruction *const ir = (ir_instruction *) instructions.pop_head();
183 
184    EXPECT_TRUE(instructions.is_empty());
185 
186    /* The resulting instruction should be 'c = -b - a'. */
187    ir_assignment *const assign = ir->as_assignment();
188    ASSERT_NE((void *)0, assign);
189 
190    EXPECT_EQ(var_c, assign->lhs->variable_referenced());
191 
192    ir_expression *const expr = assign->rhs->as_expression();
193    ASSERT_NE((void *)0, expr);
194    EXPECT_EQ(ir_binop_sub, expr->operation);
195 
196    ir_expression *const neg_b = expr->operands[0]->as_expression();
197    ir_dereference_variable *const deref_a =
198       expr->operands[1]->as_dereference_variable();
199 
200    ASSERT_NE((void *)0, deref_a);
201    EXPECT_EQ(var_a, deref_a->var);
202 
203    ASSERT_NE((void *)0, neg_b);
204 
205    ir_dereference_variable *const deref_b =
206       neg_b->operands[0]->as_dereference_variable();
207 
208    ASSERT_NE((void *)0, deref_b);
209    EXPECT_EQ(var_b, deref_b->var);
210 }
211