2
* Copyright © 2016 Intel Corporation
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:
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
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.
23
#include <gtest/gtest.h>
25
#include "ir_builder.h"
26
#include "opt_add_neg_to_sub.h"
28
using namespace ir_builder;
30
class add_neg_to_sub : public ::testing::Test {
33
virtual void TearDown();
35
exec_list instructions;
41
add_neg_to_sub_visitor v;
45
add_neg_to_sub::SetUp()
47
glsl_type_singleton_init_or_ref();
49
mem_ctx = ralloc_context(NULL);
51
instructions.make_empty();
52
body = new ir_factory(&instructions, mem_ctx);
54
var_a = new(mem_ctx) ir_variable(glsl_type::float_type,
58
var_b = new(mem_ctx) ir_variable(glsl_type::float_type,
62
var_c = new(mem_ctx) ir_variable(glsl_type::float_type,
68
add_neg_to_sub::TearDown()
76
glsl_type_singleton_decref();
79
TEST_F(add_neg_to_sub, a_plus_b)
81
body->emit(assign(var_c, add(var_a, var_b)));
83
visit_list_elements(&v, &instructions);
85
ASSERT_FALSE(instructions.is_empty());
87
ir_instruction *const ir = (ir_instruction *) instructions.pop_head();
89
EXPECT_TRUE(instructions.is_empty());
91
/* The resulting instruction should be 'c = a + b'. */
92
ir_assignment *const assign = ir->as_assignment();
93
ASSERT_NE((void *)0, assign);
95
EXPECT_EQ(var_c, assign->lhs->variable_referenced());
97
ir_expression *const expr = assign->rhs->as_expression();
98
ASSERT_NE((void *)0, expr);
99
EXPECT_EQ(ir_binop_add, expr->operation);
101
ir_dereference_variable *const deref_a =
102
expr->operands[0]->as_dereference_variable();
103
ir_dereference_variable *const deref_b =
104
expr->operands[1]->as_dereference_variable();
106
ASSERT_NE((void *)0, deref_a);
107
EXPECT_EQ(var_a, deref_a->var);
108
ASSERT_NE((void *)0, deref_b);
109
EXPECT_EQ(var_b, deref_b->var);
112
TEST_F(add_neg_to_sub, a_plus_neg_b)
114
body->emit(assign(var_c, add(var_a, neg(var_b))));
116
visit_list_elements(&v, &instructions);
118
ASSERT_FALSE(instructions.is_empty());
120
ir_instruction *const ir = (ir_instruction *) instructions.pop_head();
122
EXPECT_TRUE(instructions.is_empty());
124
/* The resulting instruction should be 'c = a - b'. */
125
ir_assignment *const assign = ir->as_assignment();
126
ASSERT_NE((void *)0, assign);
128
EXPECT_EQ(var_c, assign->lhs->variable_referenced());
130
ir_expression *const expr = assign->rhs->as_expression();
131
ASSERT_NE((void *)0, expr);
132
EXPECT_EQ(ir_binop_sub, expr->operation);
134
ir_dereference_variable *const deref_a =
135
expr->operands[0]->as_dereference_variable();
136
ir_dereference_variable *const deref_b =
137
expr->operands[1]->as_dereference_variable();
139
ASSERT_NE((void *)0, deref_a);
140
EXPECT_EQ(var_a, deref_a->var);
141
ASSERT_NE((void *)0, deref_b);
142
EXPECT_EQ(var_b, deref_b->var);
145
TEST_F(add_neg_to_sub, neg_a_plus_b)
147
body->emit(assign(var_c, add(neg(var_a), var_b)));
149
visit_list_elements(&v, &instructions);
151
ASSERT_FALSE(instructions.is_empty());
153
ir_instruction *const ir = (ir_instruction *) instructions.pop_head();
155
EXPECT_TRUE(instructions.is_empty());
157
/* The resulting instruction should be 'c = b - a'. */
158
ir_assignment *const assign = ir->as_assignment();
159
ASSERT_NE((void *)0, assign);
161
EXPECT_EQ(var_c, assign->lhs->variable_referenced());
163
ir_expression *const expr = assign->rhs->as_expression();
164
ASSERT_NE((void *)0, expr);
165
EXPECT_EQ(ir_binop_sub, expr->operation);
167
ir_dereference_variable *const deref_b =
168
expr->operands[0]->as_dereference_variable();
169
ir_dereference_variable *const deref_a =
170
expr->operands[1]->as_dereference_variable();
172
ASSERT_NE((void *)0, deref_a);
173
EXPECT_EQ(var_a, deref_a->var);
174
ASSERT_NE((void *)0, deref_b);
175
EXPECT_EQ(var_b, deref_b->var);
178
TEST_F(add_neg_to_sub, neg_a_plus_neg_b)
180
body->emit(assign(var_c, add(neg(var_a), neg(var_b))));
182
visit_list_elements(&v, &instructions);
184
ASSERT_FALSE(instructions.is_empty());
186
ir_instruction *const ir = (ir_instruction *) instructions.pop_head();
188
EXPECT_TRUE(instructions.is_empty());
190
/* The resulting instruction should be 'c = -b - a'. */
191
ir_assignment *const assign = ir->as_assignment();
192
ASSERT_NE((void *)0, assign);
194
EXPECT_EQ(var_c, assign->lhs->variable_referenced());
196
ir_expression *const expr = assign->rhs->as_expression();
197
ASSERT_NE((void *)0, expr);
198
EXPECT_EQ(ir_binop_sub, expr->operation);
200
ir_expression *const neg_b = expr->operands[0]->as_expression();
201
ir_dereference_variable *const deref_a =
202
expr->operands[1]->as_dereference_variable();
204
ASSERT_NE((void *)0, deref_a);
205
EXPECT_EQ(var_a, deref_a->var);
207
ASSERT_NE((void *)0, neg_b);
209
ir_dereference_variable *const deref_b =
210
neg_b->operands[0]->as_dereference_variable();
212
ASSERT_NE((void *)0, deref_b);
213
EXPECT_EQ(var_b, deref_b->var);