summaryrefslogtreecommitdiff
path: root/src/amd/compiler/aco_optimizer.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/amd/compiler/aco_optimizer.cpp')
-rw-r--r--src/amd/compiler/aco_optimizer.cpp46
1 files changed, 30 insertions, 16 deletions
diff --git a/src/amd/compiler/aco_optimizer.cpp b/src/amd/compiler/aco_optimizer.cpp
index a76ef116f9e..1eeef1f5bb9 100644
--- a/src/amd/compiler/aco_optimizer.cpp
+++ b/src/amd/compiler/aco_optimizer.cpp
@@ -1728,6 +1728,31 @@ bool combine_comparison_ordering(opt_ctx &ctx, aco_ptr<Instruction>& instr)
return true;
}
+bool is_operand_constant(opt_ctx &ctx, Operand op, unsigned bit_size, uint64_t *value)
+{
+ if (op.isConstant()) {
+ *value = op.constantValue64();
+ return true;
+ } else if (op.isTemp()) {
+ unsigned id = original_temp_id(ctx, op.getTemp());
+ if (!ctx.info[id].is_constant_or_literal(bit_size))
+ return false;
+ *value = get_constant_op(ctx, ctx.info[id], bit_size).constantValue64();
+ return true;
+ }
+ return false;
+}
+
+bool is_constant_nan(uint64_t value, unsigned bit_size)
+{
+ if (bit_size == 16)
+ return ((value >> 10) & 0x1f) == 0x1f && (value & 0x3ff);
+ else if (bit_size == 32)
+ return ((value >> 23) & 0xff) == 0xff && (value & 0x7fffff);
+ else
+ return ((value >> 52) & 0x7ff) == 0x7ff && (value & 0xfffffffffffff);
+}
+
/* s_or_b64(v_cmp_neq_f32(a, a), cmp(a, #b)) and b is not NaN -> get_unordered(cmp)(a, b)
* s_and_b64(v_cmp_eq_f32(a, a), cmp(a, #b)) and b is not NaN -> get_ordered(cmp)(a, b) */
bool combine_constant_comparison_ordering(opt_ctx &ctx, aco_ptr<Instruction>& instr)
@@ -1751,7 +1776,8 @@ bool combine_constant_comparison_ordering(opt_ctx &ctx, aco_ptr<Instruction>& in
else if (get_f32_cmp(nan_test->opcode) != expected_nan_test)
return false;
- if (!is_cmp(cmp->opcode) || get_cmp_bitsize(cmp->opcode) != get_cmp_bitsize(nan_test->opcode))
+ unsigned bit_size = get_cmp_bitsize(cmp->opcode);
+ if (!is_cmp(cmp->opcode) || get_cmp_bitsize(nan_test->opcode) != bit_size)
return false;
if (!nan_test->operands[0].isTemp() || !nan_test->operands[1].isTemp())
@@ -1780,22 +1806,10 @@ bool combine_constant_comparison_ordering(opt_ctx &ctx, aco_ptr<Instruction>& in
if (constant_operand == -1)
return false;
- uint32_t constant;
- if (cmp->operands[constant_operand].isConstant()) {
- constant = cmp->operands[constant_operand].constantValue();
- } else if (cmp->operands[constant_operand].isTemp()) {
- Temp tmp = cmp->operands[constant_operand].getTemp();
- unsigned id = original_temp_id(ctx, tmp);
- if (!ctx.info[id].is_constant_or_literal(32))
- return false;
- constant = ctx.info[id].val;
- } else {
+ uint64_t constant_value;
+ if (!is_operand_constant(ctx, cmp->operands[constant_operand], bit_size, &constant_value))
return false;
- }
-
- float constantf;
- memcpy(&constantf, &constant, 4);
- if (isnan(constantf))
+ if (is_constant_nan(constant_value, bit_size))
return false;
if (cmp->operands[0].isTemp())