aco: make 1/2*PI a literal constant on SI/CI
authorDaniel Schürmann <daniel@schuermann.dev>
Thu, 14 Nov 2019 07:09:32 +0000 (08:09 +0100)
committerDaniel Schürmann <daniel@schuermann.dev>
Sat, 7 Dec 2019 10:23:11 +0000 (11:23 +0100)
Reviewed-by: Rhys Perry <pendingchaos02@gmail.com>
src/amd/compiler/aco_builder_h.py
src/amd/compiler/aco_instruction_selection.cpp
src/amd/compiler/aco_ir.h
src/amd/compiler/aco_optimizer.cpp

index d215c7b198ff4db7723efe9db410b80dac1e3481..b8854810e470a9f29f27adb5c6037b2bb1416d45 100644 (file)
@@ -327,7 +327,10 @@ public:
       Operand op = op_.op;
       if (dst.regClass() == s1 && op.size() == 1 && op.isLiteral()) {
          uint32_t imm = op.constantValue();
-         if (imm >= 0xffff8000 || imm <= 0x7fff) {
+         if (imm == 0x3e22f983) {
+            if (program->chip_class >= GFX8)
+               op.setFixed(PhysReg{248}); /* it can be an inline constant on GFX8+ */
+         } else if (imm >= 0xffff8000 || imm <= 0x7fff) {
             return sopk(aco_opcode::s_movk_i32, dst, imm & 0xFFFFu);
          } else if (util_bitreverse(imm) <= 64 || util_bitreverse(imm) >= 0xFFFFFFF0) {
             uint32_t rev = util_bitreverse(imm);
index 3f741e2c0fda01d99f0074ba5cc8f44c9b398c0c..85ed7b3bf6186e24081a4a0da2076cbb58779687 100644 (file)
@@ -1660,12 +1660,8 @@ void visit_alu_instr(isel_context *ctx, nir_alu_instr *instr)
       Temp src = get_alu_src(ctx, instr->src[0]);
       aco_ptr<Instruction> norm;
       if (dst.size() == 1) {
-         Temp tmp;
-         Operand half_pi(0x3e22f983u);
-         if (src.type() == RegType::sgpr)
-            tmp = bld.vop2_e64(aco_opcode::v_mul_f32, bld.def(v1), half_pi, src);
-         else
-            tmp = bld.vop2(aco_opcode::v_mul_f32, bld.def(v1), half_pi, src);
+         Temp half_pi = bld.copy(bld.def(s1), Operand(0x3e22f983u));
+         Temp tmp = bld.vop2(aco_opcode::v_mul_f32, bld.def(v1), half_pi, as_vgpr(ctx, src));
 
          /* before GFX9, v_sin_f32 and v_cos_f32 had a valid input domain of [-256, +256] */
          if (ctx->options->chip_class < GFX9)
index 10661858ca0085cabfa017d54110263429598c7d..2928d831c8b7484294c16c30666b4facb743c6e4 100644 (file)
@@ -324,8 +324,6 @@ public:
          setFixed(PhysReg{246});
       else if (v == 0xc0800000) /* -4.0 */
          setFixed(PhysReg{247});
-      else if (v == 0x3e22f983) /* 1/(2*PI) */
-         setFixed(PhysReg{248});
       else /* Literal Constant */
          setFixed(PhysReg{255});
    };
@@ -353,8 +351,6 @@ public:
          setFixed(PhysReg{246});
       else if (v == 0xC010000000000000) /* -4.0 */
          setFixed(PhysReg{247});
-      else if (v == 0x3fc45f306dc9c882) /* 1/(2*PI) */
-         setFixed(PhysReg{248});
       else { /* Literal Constant: we don't know if it is a long or double.*/
          isConstant_ = 0;
          assert(false && "attempt to create a 64-bit literal constant");
index cea466e3819120105004a1c27bbb3aee04f1e06a..66f4db8ce0790325a916e3d43fe0ef22f2f9e1e3 100644 (file)
@@ -556,6 +556,15 @@ bool parse_base_offset(opt_ctx &ctx, Instruction* instr, unsigned op_index, Temp
    return false;
 }
 
+Operand get_constant_op(opt_ctx &ctx, uint32_t val)
+{
+   // TODO: this functions shouldn't be needed if we store Operand instead of value.
+   Operand op(val);
+   if (val == 0x3e22f983 && ctx.program->chip_class >= GFX8)
+      op.setFixed(PhysReg{248}); /* 1/2 PI can be an inline constant on GFX8+ */
+   return op;
+}
+
 void label_instruction(opt_ctx &ctx, Block& block, aco_ptr<Instruction>& instr)
 {
    if (instr->isSALU() || instr->isVALU() || instr->format == Format::PSEUDO) {
@@ -605,7 +614,7 @@ void label_instruction(opt_ctx &ctx, Block& block, aco_ptr<Instruction>& instr)
             }
          }
          if ((info.is_constant() || (info.is_literal() && instr->format == Format::PSEUDO)) && !instr->operands[i].isFixed() && can_accept_constant(instr, i)) {
-            instr->operands[i] = Operand(info.val);
+            instr->operands[i] = get_constant_op(ctx, info.val);
             continue;
          }
       }
@@ -642,15 +651,15 @@ void label_instruction(opt_ctx &ctx, Block& block, aco_ptr<Instruction>& instr)
          if (info.is_constant() && can_accept_constant(instr, i)) {
             perfwarn(instr->opcode == aco_opcode::v_cndmask_b32 && i == 2, "v_cndmask_b32 with a constant selector", instr.get());
             if (i == 0 || instr->opcode == aco_opcode::v_readlane_b32 || instr->opcode == aco_opcode::v_writelane_b32) {
-               instr->operands[i] = Operand(info.val);
+               instr->operands[i] = get_constant_op(ctx, info.val);
                continue;
             } else if (!instr->isVOP3() && can_swap_operands(instr)) {
                instr->operands[i] = instr->operands[0];
-               instr->operands[0] = Operand(info.val);
+               instr->operands[0] = get_constant_op(ctx, info.val);
                continue;
             } else if (can_use_VOP3(instr)) {
                to_VOP3(ctx, instr);
-               instr->operands[i] = Operand(info.val);
+               instr->operands[i] = get_constant_op(ctx, info.val);
                continue;
             }
          }