Lines Matching refs:operands

64  *     propagates reg->reg operands of the same type, inline constants
519 if (instr->operands.size() && instr->operands[0].isLiteral() && ctx.program->gfx_level < GFX10)
559 if (temp.bytes() != instr->operands[index].bytes())
571 if (temp.bytes() > instr->operands[index].bytes())
578 int decrease = instr->operands[index].bytes() - temp.bytes();
593 instr->operands[index].setTemp(temp);
620 instr.reset(create_instruction<VOP3_instruction>(tmp->opcode, format, tmp->operands.size(),
622 std::copy(tmp->operands.cbegin(), tmp->operands.cend(), instr->operands.begin());
697 check_vop3_operands(opt_ctx& ctx, unsigned num_operands, Operand* operands)
706 Operand op = operands[i];
748 Operand op = instr->operands[op_index];
790 if (add_instr->operands[i].isConstant()) {
791 *offset = add_instr->operands[i].constantValue() * (uint32_t)(is_sub ? -1 : 1);
792 } else if (add_instr->operands[i].isTemp() &&
793 ctx.info[add_instr->operands[i].tempId()].is_constant_or_literal(32)) {
794 *offset = ctx.info[add_instr->operands[i].tempId()].val * (uint32_t)(is_sub ? -1 : 1);
798 if (!add_instr->operands[!i].isTemp())
805 *base = add_instr->operands[!i].getTemp();
816 bool soe = smem->operands.size() >= (!smem->definitions.empty() ? 3 : 4);
817 if (soe && !smem->operands[1].isConstant())
823 Operand& op = smem->operands[soe ? smem->operands.size() - 1 : 1];
831 if (bitwise_instr->operands[0].constantEquals(-4) &&
832 bitwise_instr->operands[1].isOfType(op.regClass().type()))
833 op.setTemp(bitwise_instr->operands[1].getTemp());
834 else if (bitwise_instr->operands[1].constantEquals(-4) &&
835 bitwise_instr->operands[0].isOfType(op.regClass().type()))
836 op.setTemp(bitwise_instr->operands[0].getTemp());
843 if (!instr->operands.empty())
847 if (!instr->operands.empty() && instr->operands[1].isTemp()) {
849 ssa_info info = ctx.info[instr->operands[1].tempId()];
853 bool prevent_overflow = smem.operands[0].size() > 2 || smem.prevent_overflow;
858 instr->operands[1] = Operand::c32(info.val);
862 bool soe = smem.operands.size() >= (!smem.definitions.empty() ? 3 : 4);
864 if (ctx.info[smem.operands.back().tempId()].is_constant_or_literal(32) &&
865 ctx.info[smem.operands.back().tempId()].val == 0) {
866 smem.operands[1] = Operand::c32(offset);
867 smem.operands.back() = Operand(base);
871 smem.opcode, Format::SMEM, smem.operands.size() + 1, smem.definitions.size());
872 new_instr->operands[0] = smem.operands[0];
873 new_instr->operands[1] = Operand::c32(offset);
875 new_instr->operands[2] = smem.operands[2];
876 new_instr->operands.back() = Operand(base);
890 if (!instr->operands.empty())
898 return instr->operands[index].bytes() * 8u;
925 assert(instr->operands[i].isTemp());
928 instr->operands[i] = get_constant_op(ctx, info, bits);
971 instr->operands[i] = opsel_lo ? const_hi : const_lo;
978 instr->operands[i] = const_lo;
985 instr->operands[i] = const_hi;
992 instr->operands[i] = const_lo;
1004 instr->operands[i] = Operand::c16(const_lo.constantValue() & 0x7FFF);
1009 /* opsel must point to lo for both operands */
1028 unsigned size = instr->operands[2].constantValue() / 8;
1029 unsigned offset = instr->operands[1].constantValue() * size;
1030 bool sext = instr->operands[3].constantEquals(1);
1032 } else if (instr->opcode == aco_opcode::p_insert && instr->operands[1].constantEquals(0)) {
1033 return instr->operands[2].constantEquals(8) ? SubdwordSel::ubyte : SubdwordSel::uword;
1036 unsigned offset = instr->operands[1].constantValue() * size;
1040 assert(instr->operands[0].bytes() == 4 && instr->definitions[1].bytes() == 2);
1050 if (instr->opcode == aco_opcode::p_extract && instr->operands[3].constantEquals(0) &&
1051 instr->operands[1].constantEquals(0)) {
1052 return instr->operands[2].constantEquals(8) ? SubdwordSel::ubyte : SubdwordSel::uword;
1054 unsigned size = instr->operands[2].constantValue() / 8;
1055 unsigned offset = instr->operands[1].constantValue() * size;
1068 Temp tmp = info.instr->operands[0].getTemp();
1109 Temp tmp = info.instr->operands[0].getTemp();
1113 instr->operands[idx].set16bit(false);
1114 instr->operands[idx].set24bit(false);
1127 } else if (instr->opcode == aco_opcode::v_lshlrev_b32 && instr->operands[0].isConstant() &&
1129 ((sel.size() == 2 && instr->operands[0].constantValue() >= 16u) ||
1130 (sel.size() == 1 && instr->operands[0].constantValue() >= 24u))) {
1148 instr->operands[1] = Operand::c32(offset / size);
1149 instr->operands[2] = Operand::c32(size * 8u);
1150 instr->operands[3] = Operand::c32(sign_extend);
1164 for (unsigned i = 0; i < instr->operands.size(); i++) {
1165 Operand op = instr->operands[i];
1169 if (info.is_extract() && (info.instr->operands[0].getTemp().type() == RegType::vgpr ||
1218 if (instr->operands.size() != 2 || instr->pass_flags != pass_flags)
1220 if (!(instr->operands[0].isTemp() && instr->operands[1].isTemp()))
1222 return can_eliminate_and_exec(ctx, instr->operands[0].getTemp(), pass_flags) &&
1223 can_eliminate_and_exec(ctx, instr->operands[1].getTemp(), pass_flags);
1260 bool has_vgpr_offset = instr && !instr->operands[0].isUndefined();
1272 for (Operand& op : instr->operands)
1275 perfwarn(ctx.program, all_const, "All instruction operands are constant", instr.get());
1287 for (unsigned i = 0; i < instr->operands.size(); i++) {
1288 if (!instr->operands[i].isTemp())
1291 ssa_info info = ctx.info[instr->operands[i].tempId()];
1294 instr->operands[i] = Operand(instr->operands[i].regClass());
1296 while (info.is_temp() && info.temp.regClass() == instr->operands[i].getTemp().regClass()) {
1297 instr->operands[i].setTemp(ctx.info[instr->operands[i].tempId()].temp);
1313 !instr->operands[i].isFixed() && alu_can_accept_constant(instr->opcode, i)) {
1314 instr->operands[i] = get_constant_op(ctx, info, bits);
1323 instr->operands[i].setTemp(info.temp);
1328 instr->operands.size() == 1) {
1330 instr->operands[i].setTemp(info.temp);
1337 instr->opcode != aco_opcode::v_cndmask_b32 || instr->operands[i].getTemp().bytes() == 4;
1346 bool mod_bitsize_compat = instr->operands[i].bytes() * 8 == bits;
1350 instr->operands[i].setTemp(info.temp);
1353 instr->operands[i].setTemp(info.temp);
1358 instr->operands[i].setTemp(info.temp);
1370 instr->operands[i] = Operand(info.temp);
1393 instr->operands[i] = op;
1396 instr->operands[i] = instr->operands[0];
1397 instr->operands[0] = op;
1401 instr->operands[i] = op;
1426 instr->operands[1] = Operand(v1);
1431 instr->operands[2] = Operand::c32(0);
1439 instr->operands[1].setTemp(base);
1444 instr->operands[i].setTemp(base);
1459 base.regClass() == instr->operands[i].regClass() &&
1461 instr->operands[i].setTemp(base);
1468 instr->operands[i] = Operand(instr->operands[i].regClass());
1483 base.regClass() == instr->operands[i].regClass() &&
1506 instr->operands[i].setTemp(base);
1512 instr->operands[i].setTemp(base);
1520 if (ctx.info[instr->operands[0].tempId()].is_scc_invert()) {
1524 instr->operands[0].setTemp(ctx.info[instr->operands[0].tempId()].temp);
1540 unsigned ops = instr->opcode == aco_opcode::v_cndmask_b32 ? 2 : instr->operands.size();
1542 canonicalized = is_op_canonicalized(ctx, instr->operands[i]);
1561 bool copy_prop = instr->operands.size() == 1 && instr->operands[0].isTemp() &&
1562 instr->operands[0].regClass() == instr->definitions[0].regClass();
1564 ctx.info[instr->definitions[0].tempId()].set_temp(instr->operands[0].getTemp());
1568 /* expand vector operands */
1571 for (const Operand& op : instr->operands) {
1572 /* ensure that any expanded operands are properly aligned */
1577 for (const Operand& vec_op : vec->operands)
1584 /* combine expanded operands to new vector */
1585 if (ops.size() != instr->operands.size()) {
1586 assert(ops.size() > instr->operands.size());
1594 instr->operands[i] = ops[i];
1599 assert(instr->operands[i] == ops[i]);
1604 if (instr->operands.size() == 2) {
1606 if (instr->operands[1].isTemp() && ctx.info[instr->operands[1].tempId()].is_split()) {
1607 Instruction* split = ctx.info[instr->operands[1].tempId()].instr;
1608 if (instr->operands[0].isTemp() &&
1609 instr->operands[0].getTemp() == split->definitions[0].getTemp())
1610 ctx.info[instr->definitions[0].tempId()].set_temp(split->operands[0].getTemp());
1616 ssa_info& info = ctx.info[instr->operands[0].tempId()];
1627 if (instr->definitions.size() == 2 && instr->operands[0].isTemp() &&
1630 if (instr->operands[0].bytes() == 4) {
1632 ctx.info[instr->definitions[0].tempId()].set_temp(instr->operands[0].getTemp());
1639 Instruction* vec = ctx.info[instr->operands[0].tempId()].instr;
1645 while (vec_offset < split_offset && vec_index < vec->operands.size())
1646 vec_offset += vec->operands[vec_index++].bytes();
1649 vec->operands[vec_index].bytes() != instr->definitions[i].bytes())
1652 Operand vec_op = vec->operands[vec_index];
1666 ssa_info& info = ctx.info[instr->operands[0].tempId()];
1667 const unsigned index = instr->operands[1].constantValue();
1675 for (const Operand& op : vec->operands) {
1682 instr->operands[0] = op;
1689 instr->operands[0] =
1694 if (instr->operands[0].bytes() != instr->definitions[0].bytes()) {
1695 if (instr->operands[0].size() != 1)
1699 ctx.info[instr->definitions[0].tempId()].set_temp(instr->operands[0].getTemp());
1707 instr->operands.pop_back();
1711 if (instr->operands[0].isTemp() && ctx.info[instr->operands[0].tempId()].is_vec() &&
1712 instr->operands[0].regClass() != instr->definitions[0].regClass()) {
1716 Instruction* vec = ctx.info[instr->operands[0].tempId()].instr;
1720 aco_opcode::p_create_vector, Format::PSEUDO, vec->operands.size(), 1));
1722 std::copy(vec->operands.begin(), vec->operands.end(), instr->operands.begin());
1723 for (unsigned i = 0; i < vec->operands.size(); i++) {
1724 Operand& op = instr->operands[i];
1738 } else if (instr->operands[0].isConstant()) {
1740 ctx.program->gfx_level, instr->operands[0].constantValue64());
1741 } else if (instr->operands[0].isTemp()) {
1742 ctx.info[instr->definitions[0].tempId()].set_temp(instr->operands[0].getTemp());
1743 if (ctx.info[instr->operands[0].tempId()].is_canonicalized())
1746 assert(instr->operands[0].isFixed());
1773 if (instr->operands[!i].isConstant() && instr->operands[i].isTemp()) {
1775 (instr->operands[!i].constantEquals(fp16 ? 0x3c00 : 0x3f800000) || /* 1.0 */
1776 instr->operands[!i].constantEquals(fp16 ? 0xbc00 : 0xbf800000u))) { /* -1.0 */
1777 bool neg1 = instr->operands[!i].constantEquals(fp16 ? 0xbc00 : 0xbf800000u);
1786 Temp other = instr->operands[i].getTemp();
1797 } else if (instr->operands[!i].constantValue() ==
1799 ctx.info[instr->operands[i].tempId()].set_omod2(instr.get());
1800 } else if (instr->operands[!i].constantValue() ==
1802 ctx.info[instr->operands[i].tempId()].set_omod4(instr.get());
1803 } else if (instr->operands[!i].constantValue() ==
1805 ctx.info[instr->operands[i].tempId()].set_omod5(instr.get());
1806 } else if (instr->operands[!i].constantValue() == 0u &&
1835 if (instr->operands[i].constantEquals(0))
1837 else if (instr->operands[i].constantEquals(is_fp16 ? 0x3c00 : 0x3f800000)) /* 1.0 */
1842 if (found_zero && found_one && instr->operands[idx].isTemp())
1843 ctx.info[instr->operands[idx].tempId()].set_clamp(instr.get());
1847 if (instr->operands[0].constantEquals(0) && instr->operands[1].constantEquals(0xFFFFFFFF))
1848 ctx.info[instr->definitions[0].tempId()].set_vcc(instr->operands[2].getTemp());
1849 else if (instr->operands[0].constantEquals(0) &&
1850 instr->operands[1].constantEquals(0x3f800000u))
1851 ctx.info[instr->definitions[0].tempId()].set_b2f(instr->operands[2].getTemp());
1852 else if (instr->operands[0].constantEquals(0) && instr->operands[1].constantEquals(1))
1853 ctx.info[instr->definitions[0].tempId()].set_b2i(instr->operands[2].getTemp());
1858 instr->operands[0].constantEquals(0) && instr->operands[1].isTemp() &&
1859 ctx.info[instr->operands[1].tempId()].is_vcc())
1861 ctx.info[instr->operands[1].tempId()].temp);
1865 bool all_same_temp = instr->operands[0].isTemp();
1868 all_same_temp = instr->definitions[0].regClass() == instr->operands[0].regClass();
1869 for (unsigned i = 1; all_same_temp && (i < instr->operands.size()); i++) {
1870 if (!instr->operands[i].isTemp() ||
1871 instr->operands[i].tempId() != instr->operands[0].tempId())
1875 ctx.info[instr->definitions[0].tempId()].set_temp(instr->operands[0].getTemp());
1877 bool all_undef = instr->operands[0].isUndefined();
1878 for (unsigned i = 1; all_undef && (i < instr->operands.size()); i++) {
1879 if (!instr->operands[i].isUndefined())
1906 if (ctx.info[instr->operands[0].tempId()].is_uniform_bool()) {
1909 ctx.info[instr->operands[0].tempId()].temp);
1910 } else if (ctx.info[instr->operands[0].tempId()].is_uniform_bitwise()) {
1913 ctx.info[instr->operands[0].tempId()].instr->definitions[1].getTemp());
1919 if (fixed_to_exec(instr->operands[1]) && instr->operands[0].isTemp()) {
1920 if (ctx.info[instr->operands[0].tempId()].is_uniform_bool()) {
1924 ctx.info[instr->operands[0].tempId()].temp);
1926 ctx.info[instr->operands[0].tempId()].temp);
1928 } else if (ctx.info[instr->operands[0].tempId()].is_uniform_bitwise()) {
1932 ctx.info[instr->operands[0].tempId()].instr->definitions[1].getTemp());
1934 ctx.info[instr->operands[0].tempId()].instr->definitions[1].getTemp());
1941 ctx.info[instr->definitions[0].tempId()].set_temp(instr->operands[0].getTemp());
1943 } else if (can_eliminate_and_exec(ctx, instr->operands[0].getTemp(), instr->pass_flags)) {
1944 ctx.info[instr->definitions[0].tempId()].set_temp(instr->operands[0].getTemp());
1953 if (std::all_of(instr->operands.begin(), instr->operands.end(),
1991 if (instr->operands[0].constantEquals((unsigned)-1) && instr->operands[1].constantEquals(0)) {
1993 ctx.info[instr->definitions[0].tempId()].set_uniform_bool(instr->operands[2].getTemp());
1995 if (instr->operands[2].isTemp() && ctx.info[instr->operands[2].tempId()].is_scc_invert()) {
1996 /* Flip the operands to get rid of the scc_invert instruction */
1997 std::swap(instr->operands[0], instr->operands[1]);
1998 instr->operands[2].setTemp(ctx.info[instr->operands[2].tempId()].temp);
2002 if (instr->operands[0].isTemp() && ctx.info[instr->operands[0].tempId()].is_scc_invert()) {
2003 ctx.info[instr->definitions[0].tempId()].set_temp(instr->operands[0].getTemp());
2009 if (instr->operands[0].constantEquals(0x3f800000u))
2015 if (instr->operands[0].regClass() == v1 && parse_insert(instr.get()))
2016 ctx.info[instr->operands[0].tempId()].set_insert(instr.get());
2021 if (instr->operands[0].bytes() == 4) {
2022 if (instr->operands[0].regClass() == v1)
2023 ctx.info[instr->operands[0].tempId()].set_insert(instr.get());
2038 if (instr->operands[0].isTemp())
2039 ctx.info[instr->operands[0].tempId()].set_f2f16(instr.get());
2043 if (instr->operands[0].isTemp())
2069 for (const Operand& op : instr->operands) {
2115 op_instr[i] = follow_operand(ctx, instr->operands[i], true);
2126 if (!op_instr[i]->operands[0].isTemp() || !op_instr[i]->operands[1].isTemp())
2141 Temp op0 = op_instr[i]->operands[0].getTemp();
2142 Temp op1 = op_instr[i]->operands[1].getTemp();
2180 new_instr->operands[0] = Operand(op[0]);
2181 new_instr->operands[1] = Operand(op[1]);
2205 Instruction* nan_test = follow_operand(ctx, instr->operands[0], true);
2206 Instruction* cmp = follow_operand(ctx, instr->operands[1], true);
2220 if (!nan_test->operands[0].isTemp() || !nan_test->operands[1].isTemp())
2222 if (!cmp->operands[0].isTemp() || !cmp->operands[1].isTemp())
2225 unsigned prop_cmp0 = original_temp_id(ctx, cmp->operands[0].getTemp());
2226 unsigned prop_cmp1 = original_temp_id(ctx, cmp->operands[1].getTemp());
2227 unsigned prop_nan0 = original_temp_id(ctx, nan_test->operands[0].getTemp());
2228 unsigned prop_nan1 = original_temp_id(ctx, nan_test->operands[1].getTemp());
2234 ctx.uses[cmp->operands[0].tempId()]++;
2235 ctx.uses[cmp->operands[1].tempId()]++;
2254 new_instr->operands[0] = cmp->operands[0];
2255 new_instr->operands[1] = cmp->operands[1];
2305 Instruction* nan_test = follow_operand(ctx, instr->operands[0], true);
2306 Instruction* cmp = follow_operand(ctx, instr->operands[1], true);
2323 if (!nan_test->operands[0].isTemp() || !nan_test->operands[1].isTemp())
2325 if (!cmp->operands[0].isTemp() && !cmp->operands[1].isTemp())
2328 unsigned prop_nan0 = original_temp_id(ctx, nan_test->operands[0].getTemp());
2329 unsigned prop_nan1 = original_temp_id(ctx, nan_test->operands[1].getTemp());
2342 if (cmp->operands[i].isTemp() &&
2343 original_temp_id(ctx, cmp->operands[i].getTemp()) == prop_nan0) {
2352 if (!is_operand_constant(ctx, cmp->operands[constant_operand], bit_size, &constant_value))
2357 if (cmp->operands[0].isTemp())
2358 ctx.uses[cmp->operands[0].tempId()]++;
2359 if (cmp->operands[1].isTemp())
2360 ctx.uses[cmp->operands[1].tempId()]++;
2379 new_instr->operands[0] = cmp->operands[0];
2380 new_instr->operands[1] = cmp->operands[1];
2395 if (!instr->operands[0].isFixed() || instr->operands[0].physReg() != exec)
2400 Instruction* cmp = follow_operand(ctx, instr->operands[1]);
2408 if (cmp->operands[0].isTemp())
2409 ctx.uses[cmp->operands[0].tempId()]++;
2410 if (cmp->operands[1].isTemp())
2411 ctx.uses[cmp->operands[1].tempId()]++;
2458 new_instr->operands[0] = cmp->operands[0];
2459 new_instr->operands[1] = cmp->operands[1];
2474 const char* shuffle_str, Operand operands[3], bool neg[3], bool abs[3],
2482 Instruction* op2_instr = follow_operand(ctx, op1_instr->operands[swap]);
2485 if (fixed_to_exec(op2_instr->operands[0]) || fixed_to_exec(op2_instr->operands[1]))
2500 /* get operands and modifiers and check inbetween modifiers */
2526 operands[shuffle[0]] = op1_instr->operands[!swap];
2533 operands[shuffle[i + 1]] = op2_instr->operands[i];
2540 /* check operands */
2541 if (!check_vop3_operands(ctx, 3, operands))
2549 Operand operands[3], bool neg[3], bool abs[3], uint8_t opsel, bool clamp,
2558 new_instr->operands[0] = operands[0];
2559 new_instr->operands[1] = operands[1];
2560 new_instr->operands[2] = operands[2];
2575 Operand operands[3];
2578 if (match_op3_for_vop3(ctx, instr->opcode, op2, instr.get(), swap, shuffle, operands, neg,
2580 ctx.uses[instr->operands[swap].tempId()]--;
2581 create_vop3_for_op3(ctx, new_op, instr, operands, neg, abs, opsel, clamp, omod);
2615 Instruction* extins = follow_operand(ctx, instr->operands[i]);
2620 Operand operands[3];
2623 (extins->operands[1].constantValue() + 1) * extins->operands[2].constantValue() == 32) {
2625 operands[1] =
2626 Operand::c32(extins->operands[1].constantValue() * extins->operands[2].constantValue());
2630 extins->operands[3].constantEquals(0))) &&
2631 extins->operands[1].constantEquals(0)) {
2633 operands[1] = Operand::c32(extins->operands[2].constantEquals(8) ? 0xffu : 0xffffu);
2638 operands[0] = extins->operands[0];
2639 operands[2] = instr->operands[!i];
2641 if (!check_vop3_operands(ctx, 3, operands))
2650 ctx.uses[instr->operands[i].tempId()]--;
2651 create_vop3_for_op3(ctx, op, instr, operands, neg, abs, opsel, clamp, omod);
2668 Operand operands[3];
2672 if (match_op3_for_vop3(ctx, instr->opcode, opposite, instr.get(), swap, "012", operands, neg,
2675 ctx.uses[instr->operands[swap].tempId()]--;
2678 create_vop3_for_op3(ctx, minmax3, instr, operands, neg, abs, opsel, clamp, omod);
2695 if (!instr->operands[0].isTemp())
2700 Instruction* op2_instr = follow_operand(ctx, instr->operands[0]);
2716 ctx.uses[instr->operands[0].tempId()]--;
2743 Instruction* op2_instr = follow_operand(ctx, instr->operands[i]);
2747 if (ctx.uses[op2_instr->definitions[1].tempId()] || fixed_to_exec(op2_instr->operands[0]))
2750 if (instr->operands[!i].isLiteral() && op2_instr->operands[0].isLiteral() &&
2751 instr->operands[!i].constantValue() != op2_instr->operands[0].constantValue())
2754 ctx.uses[instr->operands[i].tempId()]--;
2755 instr->operands[0] = instr->operands[!i];
2756 instr->operands[1] = op2_instr->operands[0];
2780 Instruction* op2_instr = follow_operand(ctx, instr->operands[i], true);
2784 if (!op2_instr->operands[1].isConstant() || fixed_to_exec(op2_instr->operands[0]))
2787 uint32_t shift = op2_instr->operands[1].constantValue();
2791 if (instr->operands[!i].isLiteral() && op2_instr->operands[0].isLiteral() &&
2792 instr->operands[!i].constantValue() != op2_instr->operands[0].constantValue())
2795 ctx.uses[instr->operands[i].tempId()]--;
2796 instr->operands[1] = instr->operands[!i];
2797 instr->operands[0] = op2_instr->operands[0];
2818 if (instr->operands[i].isTemp() && ctx.info[instr->operands[i].tempId()].is_b2i() &&
2819 ctx.uses[instr->operands[i].tempId()] == 1) {
2822 if (instr->operands[!i].isTemp() &&
2823 instr->operands[!i].getTemp().type() == RegType::vgpr) {
2826 (instr->operands[!i].isConstant() && !instr->operands[!i].isLiteral())) {
2832 ctx.uses[instr->operands[i].tempId()]--;
2844 new_instr->operands[0] = Operand::zero();
2845 new_instr->operands[1] = instr->operands[!i];
2846 new_instr->operands[2] = Operand(ctx.info[instr->operands[i].tempId()].temp);
2863 Instruction* op_instr = follow_operand(ctx, instr->operands[i]);
2865 !op_instr->usesModifiers() && op_instr->operands[0].isTemp() &&
2866 op_instr->operands[0].getTemp().type() == RegType::vgpr &&
2867 op_instr->operands[1].constantEquals(0)) {
2870 ctx.uses[instr->operands[i].tempId()]--;
2871 new_instr->operands[0] = op_instr->operands[0];
2872 new_instr->operands[1] = instr->operands[!i];
2943 Operand operands[3];
2946 if (match_op3_for_vop3(ctx, instr->opcode, other_op, instr.get(), swap, "012", operands, neg,
2960 if (operands[i].isConstant()) {
2961 val = hi16 ? operands[i].constantValue16(true) : operands[i].constantValue();
2962 } else if (operands[i].isTemp() &&
2963 ctx.info[operands[i].tempId()].is_constant_or_literal(32)) {
2964 val = ctx.info[operands[i].tempId()].val >> (hi16 ? 16 : 0);
3038 ctx.uses[instr->operands[swap].tempId()]--;
3039 create_vop3_for_op3(ctx, med, instr, operands, neg, abs, opsel, clamp, omod);
3059 for (unsigned i = 0; i < instr->operands.size(); i++) {
3060 if (instr->operands[i].isLiteral())
3062 if (!instr->operands[i].isTemp())
3064 if (instr->operands[i].getTemp().type() == RegType::sgpr) {
3065 if (instr->operands[i].tempId() != sgpr_ids[0])
3066 sgpr_ids[!!sgpr_ids[0]] = instr->operands[i].tempId();
3068 ssa_info& info = ctx.info[instr->operands[i].tempId()];
3071 if (info.is_extract() && info.instr->operands[0].getTemp().type() == RegType::sgpr)
3090 uint16_t uses = ctx.uses[instr->operands[i].tempId()];
3093 sgpr_info_id = instr->operands[i].tempId();
3107 Temp sgpr = info.is_extract() ? info.instr->operands[0].getTemp() : info.temp;
3122 instr->operands[sgpr_idx] = Operand(sgpr);
3124 instr->operands[sgpr_idx] = instr->operands[0];
3125 instr->operands[0] = Operand(sgpr);
3131 instr->operands[sgpr_idx] = Operand(sgpr);
3270 if (!ctx.info[extract->operands[0].tempId()].is_usedef() ||
3271 ctx.uses[extract->operands[0].tempId()] > 1)
3275 Instruction* ds = ctx.info[extract->operands[0].tempId()].instr;
3279 unsigned extract_idx = extract->operands[1].constantValue();
3280 unsigned bits_extracted = extract->operands[2].constantValue();
3281 unsigned sign_ext = extract->operands[3].constantValue();
3322 Instruction* op_instr = follow_operand(ctx, instr->operands[i], true);
3324 op_instr->operands[0].constantEquals(0) && op_instr->operands[1].constantEquals(0) &&
3328 if (instr->operands[!i].isTemp() &&
3329 instr->operands[!i].getTemp().type() == RegType::vgpr) {
3333 (instr->operands[!i].isConstant() && !instr->operands[!i].isLiteral())) {
3340 ctx.uses[instr->operands[i].tempId()]--;
3341 if (ctx.uses[instr->operands[i].tempId()])
3342 ctx.uses[op_instr->operands[2].tempId()]++;
3344 new_instr->operands[0] = Operand::zero();
3345 new_instr->operands[1] = instr->operands[!i];
3346 new_instr->operands[2] = Operand(op_instr->operands[2]);
3373 /* Don't allow 24-bit operands on subtraction because
3379 Instruction* op_instr = follow_operand(ctx, instr->operands[i]);
3389 if (op_instr->operands[shift_op_idx].isConstant() &&
3390 ((allow_24bit && op_instr->operands[!shift_op_idx].is24bit()) ||
3391 op_instr->operands[!shift_op_idx].is16bit())) {
3392 uint32_t multiplier = 1 << (op_instr->operands[shift_op_idx].constantValue() % 32u);
3399 op_instr->operands[!shift_op_idx],
3401 instr->operands[!i],
3406 ctx.uses[instr->operands[i].tempId()]--;
3412 new_instr->operands[op_idx] = ops[op_idx];
3426 /* propagate swizzles which apply to a result down to the instruction's operands:
3452 if (instr->opcode == aco_opcode::v_pk_mul_f16 && instr->operands[1].constantEquals(0x3C00) &&
3453 vop3p->clamp && instr->operands[0].isTemp() && ctx.uses[instr->operands[0].tempId()] == 1 &&
3456 ssa_info& info = ctx.info[instr->operands[0].tempId()];
3458 VOP3P_instruction* candidate = &ctx.info[instr->operands[0].tempId()].instr->vop3p();
3470 for (unsigned i = 0; i < instr->operands.size(); i++) {
3471 Operand& op = instr->operands[i];
3477 info.instr->operands[1].constantEquals(0x3C00)) {
3485 for (unsigned j = 0; j < instr->operands.size(); j++)
3486 ops[j] = instr->operands[j];
3487 ops[i] = info.instr->operands[0];
3488 if (!check_vop3_operands(ctx, instr->operands.size(), ops))
3493 instr->operands[i] = fneg->operands[0];
3509 ctx.uses[fneg->operands[0].tempId()]++;
3526 if (!instr->operands[i].isTemp() || !ctx.info[instr->operands[i].tempId()].is_vop3p())
3528 ssa_info& info = ctx.info[instr->operands[i].tempId()];
3538 Operand op[3] = {info.instr->operands[0], info.instr->operands[1], instr->operands[1 - i]};
3539 if (ctx.uses[instr->operands[i].tempId()] >= uses || !check_vop3_operands(ctx, 3, op))
3550 uses = ctx.uses[instr->operands[i].tempId()];
3557 Operand op[3] = {mul_instr->operands[0], mul_instr->operands[1], instr->operands[add_op_idx]};
3573 fma->operands[i] = op[i];
3577 fma->operands[2] = op[2];
3636 for (unsigned i = 0; i < instr->operands.size(); i++) {
3637 vop3p->operands[is_add + i] = instr->operands[i];
3646 vop3p->operands[2] = Operand::zero();
3650 vop3p->operands[0] = Operand::c32(0x3f800000);
3701 for (unsigned i = 0; i < instr->operands.size(); i++) {
3702 if (!instr->operands[i].isTemp())
3704 Temp tmp = instr->operands[i].getTemp();
3721 /* Conversion to VOP3P will add inline constant operands, but that shouldn't affect
3724 for (unsigned j = 0; j < instr->operands.size(); j++)
3725 op[j] = instr->operands[j];
3726 op[i] = conv->operands[0];
3727 if (!check_vop3_operands(ctx, instr->operands.size(), op))
3738 ctx.uses[conv->operands[0].tempId()]++;
3739 instr->operands[i].setTemp(conv->operands[0].getTemp());
3793 for (unsigned i = 0; i < instr->operands.size(); i++) {
3794 Operand& op = instr->operands[i];
3807 (info.instr->operands[0].getTemp().type() == RegType::vgpr ||
3808 instr->operands[i].getTemp().type() == RegType::sgpr) &&
3812 if (--ctx.uses[instr->operands[i].tempId()])
3813 ctx.uses[info.instr->operands[0].tempId()]++;
3814 instr->operands[i].setTemp(info.instr->operands[0].getTemp());
3834 ssa_info& info = ctx.info[instr->operands[0].tempId()];
3837 if (--ctx.uses[instr->operands[0].tempId()])
3838 ctx.uses[info.instr->operands[0].tempId()]++;
3839 instr->operands[0].setTemp(info.instr->operands[0].getTemp());
3857 ctx.uses[instr->operands[1].tempId()] == 1) {
3865 if (mul_instr->operands[0].isLiteral())
3884 instr->operands[0] = mul_instr->operands[0];
3885 instr->operands[1] = mul_instr->operands[1];
3912 ((instr->operands[0].constantEquals(0x3f800000) && (instr->vop3p().opsel_hi & 0x1) == 0) ||
3913 (instr->operands[0].constantEquals(0x3C00) && (instr->vop3p().opsel_hi & 0x1) &&
3926 for (unsigned i = is_add_mix ? 1 : 0; i < instr->operands.size(); i++) {
3927 if (!instr->operands[i].isTemp() || !ctx.info[instr->operands[i].tempId()].is_mul())
3929 ssa_info& info = ctx.info[instr->operands[i].tempId()];
3952 bool is_fma_precise = is_pow_of_two(ctx, info.instr->operands[0]) ||
3953 is_pow_of_two(ctx, info.instr->operands[1]);
3973 Operand op[3] = {info.instr->operands[0], info.instr->operands[1],
3974 instr->operands[candidate_add_op_idx]};
3976 ctx.uses[instr->operands[i].tempId()] > uses)
3979 if (ctx.uses[instr->operands[i].tempId()] == uses) {
3988 uses = ctx.uses[instr->operands[i].tempId()];
3994 Operand op[3] = {mul_instr->operands[0], mul_instr->operands[1],
3995 instr->operands[add_op_idx]};
4075 mad->operands[i] = op[i];
4101 mad->operands[i] = op[i];
4124 if (instr->operands[i].isTemp() && ctx.info[instr->operands[i].tempId()].is_b2f() &&
4125 ctx.uses[instr->operands[i].tempId()] == 1 && instr->operands[!i].isTemp() &&
4126 instr->operands[!i].getTemp().type() == RegType::vgpr) {
4127 ctx.uses[instr->operands[i].tempId()]--;
4128 ctx.uses[ctx.info[instr->operands[i].tempId()].temp.id()]++;
4132 new_instr->operands[0] = Operand::zero();
4133 new_instr->operands[1] = instr->operands[!i];
4134 new_instr->operands[2] = Operand(ctx.info[instr->operands[i].tempId()].temp);
4247 for (Operand& op : instr->operands) {
4266 for (Operand& op : instr->operands) {
4291 assert(instr->operands[0].regClass() == s1);
4292 assert(instr->operands[1].regClass() == s1);
4320 if (num_used == 1 && ctx.info[instr->operands[0].tempId()].is_vec() &&
4321 ctx.uses[instr->operands[0].tempId()] == 1) {
4322 Instruction* vec = ctx.info[instr->operands[0].tempId()].instr;
4326 for (Operand& vec_op : vec->operands) {
4333 if (off != instr->operands[0].bytes() && op.bytes() == instr->definitions[idx].bytes()) {
4334 ctx.uses[instr->operands[0].tempId()]--;
4335 for (Operand& vec_op : vec->operands) {
4344 extract->operands[0] = op;
4353 instr->operands[0].bytes() % instr->definitions[idx].bytes() == 0 &&
4357 extract->operands[0] = instr->operands[0];
4358 extract->operands[1] =
4371 if (instr->operands[0].isTemp())
4372 ctx.uses[instr->operands[0].tempId()]--;
4373 if (instr->operands[1].isTemp())
4374 ctx.uses[instr->operands[1].tempId()]--;
4397 if (instr->operands[2].isTemp() &&
4398 ctx.info[instr->operands[2].tempId()].is_literal(get_operand_size(instr, 2))) {
4402 if (!instr->operands[i].isTemp())
4404 has_sgpr |= instr->operands[i].getTemp().type() == RegType::sgpr;
4405 has_vgpr |= instr->operands[i].getTemp().type() == RegType::vgpr;
4412 literal_uses = ctx.uses[instr->operands[2].tempId()];
4418 if (instr->operands[2].isTemp() && instr->operands[2].getTemp().type() == RegType::vgpr) {
4420 if (!instr->operands[i].isTemp())
4424 if (ctx.program->gfx_level < GFX10 && instr->operands[!i].isTemp() &&
4425 instr->operands[!i].getTemp().type() == RegType::sgpr)
4428 if (ctx.info[instr->operands[i].tempId()].is_literal(get_operand_size(instr, i)) &&
4429 ctx.uses[instr->operands[i].tempId()] < literal_uses) {
4431 literal_uses = ctx.uses[instr->operands[i].tempId()];
4444 ctx.uses[instr->operands[literal_idx].tempId()]--;
4454 if (instr->isBranch() && instr->operands.size() && instr->operands[0].isTemp() &&
4455 instr->operands[0].isFixed() && instr->operands[0].physReg() == scc) {
4456 ctx.info[instr->operands[0].tempId()].set_scc_needed();
4460 instr->operands[2].isTemp()) {
4461 ctx.info[instr->operands[2].tempId()].set_scc_needed();
4462 } else if (instr->opcode == aco_opcode::p_wqm && instr->operands[0].isTemp() &&
4465 ctx.info[instr->operands[0].tempId()].set_scc_needed();
4494 for (unsigned i = 0; i < instr->operands.size(); i++) {
4495 if (!instr->operands[i].isTemp())
4497 ssa_info info = ctx.info[instr->operands[i].tempId()];
4511 std::swap(instr->operands[0], instr->operands[1]);
4517 std::swap(instr->operands[0], instr->operands[1]);
4527 ctx.uses[info.instr->operands[0].tempId()]++;
4528 instr->operands[0].setTemp(info.instr->operands[0].getTemp());
4547 num_operands = instr->operands.size();
4549 else if (instr->isVALU() && instr->operands.size() >= 3)
4558 Operand op = instr->operands[i];
4605 if (instr->operands[i].isTemp() && instr->operands[i].tempId() == literal_id)
4606 ctx.uses[instr->operands[i].tempId()]--;
4671 if (instr->operands[0].isLiteral()) {
4672 std::swap(instr->operands[0], instr->operands[1]);
4676 if (!instr->operands[1].isLiteral())
4679 if (instr->operands[0].isFixed() && instr->operands[0].physReg() >= 128)
4682 uint32_t value = instr->operands[1].constantValue();
4713 instr_sopk->imm = instr_sopk->operands[1].constantValue() & 0xffff;
4715 instr_sopk->operands.pop_back();
4729 (ctx.uses[instr->operands[info->literal_idx].tempId()] == 0 || info->literal_idx == 2)) {
4744 new_mad->operands[0] = instr->operands[0];
4745 new_mad->operands[1] = instr->operands[1];
4746 if (!new_mad->operands[1].isTemp() ||
4747 new_mad->operands[1].getTemp().type() == RegType::sgpr)
4748 std::swap(new_mad->operands[0], new_mad->operands[1]);
4750 new_mad->operands[0] = instr->operands[1 - info->literal_idx];
4751 new_mad->operands[1] = instr->operands[2];
4753 new_mad->operands[2] =
4754 Operand::c32(ctx.info[instr->operands[info->literal_idx].tempId()].val);
4763 for (unsigned i = 0; i < instr->operands.size(); i++) {
4764 Operand op = instr->operands[i];
4771 instr->operands[i] = literal;
4781 (instr->operands[0].isLiteral() || instr->operands[1].isLiteral()))