Skip to content

[TableGen][GISel] Create untyped registers during instruction selection #121270

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 2 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 6 additions & 2 deletions llvm/include/llvm/CodeGen/GlobalISel/GIMatchTableExecutor.h
Original file line number Diff line number Diff line change
Expand Up @@ -550,10 +550,14 @@ enum {
/// Combines both a GIR_EraseFromParent 0 + GIR_Done
GIR_EraseRootFromParent_Done,

/// Create a new temporary register that's not constrained.
/// Create a new generic temporary register that's not constrained.
/// - TempRegID(ULEB128) - The temporary register ID to initialize.
/// - Ty(1) - Expected type
GIR_MakeTempReg,
GIR_MakeGenericTempReg,

/// Create a new virtual temporary register that doesn't have register class.
/// - TempRegID(ULEB128) - The temporary register ID to initialize.
GIR_MakeVirtualTempReg,

/// Replaces all references to a register from an instruction
/// with another register from another instruction.
Expand Down
21 changes: 17 additions & 4 deletions llvm/include/llvm/CodeGen/GlobalISel/GIMatchTableExecutorImpl.h
Original file line number Diff line number Diff line change
Expand Up @@ -1485,15 +1485,28 @@ bool GIMatchTableExecutor::executeMatchTable(
propagateFlags();
return true;
}
case GIR_MakeTempReg: {
case GIR_MakeGenericTempReg: {
uint64_t TempRegID = readULEB();
int TypeID = readS8();

State.TempRegisters[TempRegID] =
MRI.createGenericVirtualRegister(getTypeFromIdx(TypeID));
DEBUG_WITH_TYPE(TgtExecutor::getName(),
dbgs() << CurrentIdx << ": TempRegs[" << TempRegID
<< "] = GIR_MakeTempReg(" << TypeID << ")\n");
DEBUG_WITH_TYPE(TgtExecutor::getName(), {
dbgs() << CurrentIdx << ": TempRegs[" << TempRegID
<< "] = GIR_MakeGenericTempReg(" << TypeID << ")\n";
});
break;
}
case GIR_MakeVirtualTempReg: {
uint64_t TempRegID = readULEB();

Register Reg = MRI.createIncompleteVirtualRegister();
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Where does the class get set here? I'd expect any create action to carry the class at least

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The class is set by constrainOperandRegClass() called when executing a subsequent GIR_ConstrainOperandRC or GIR_[Root]ConstrainSelectedInstOperands action. This function doesn't seem to query a virtual register's type, but it calls a few TII / TRI hooks (e.g. TRI.getConstrainedRegClassForOperand()) that might in theory do that.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In general that would need the type. I think it's a bad idea to let this be so far removed, and tablegen needs to supply the class to use

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

tablegen needs to supply the class to use

This doesn't seem possible ATM. Producer and consumer of a virtual register might not agree on register class, in which case constrainOperandRegClass would split it into two virtual registers and insert a cross-class copy. We would need to lift this machinery to tablegen level. I'm not sure this is what we want or if it's even possible?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If we want to provide the register class for temporaries right when creating them, it will need larger refactoring.

Specifically, we will need to provide the desired register class(-es) to node importing functions, or create temporaries in advance and pass them to these functions. This is necessary for leaf nodes that don't know the resulting register class, and may also be useful for instruction nodes so that we can generate a cross-class copy(-es) if necessary.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm confused.

An additional copy is only needed if getCommonSubClass for the producer and consumer can't find anything. I guess we could handle that in the selector implementation

If we delay emitting this copy, then the register's class would be invalid for the consumer and we shouldn't make decisions based on invalid register class either.

this doesn't work for instructions that do not have concrete register class constraints

This is new to me. How can instruction's register operand not have a concrete register class?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

To be clear I am 100% against passing around incomplete virtual registers. Incomplete virtual registers are an implementation detail of virtual registers that are not part of the contract of valid MIR that code should have to reason about.

This is new to me. How can instruction's register operand not have a concrete register class?

This is all generic instructions like COPY and IMPLICIT_DEF, but targets can do the same with their own pseudos. This is part of why the tablegen forms of EXTRACT_SUBREG need an explicit register class operand

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

To be clear I am 100% against passing around incomplete virtual registers. Incomplete virtual registers are an implementation detail of virtual registers that are not part of the contract of valid MIR that code should have to reason about.

I see your point and I can agree with it.

If we delay emitting this copy, then the register's class would be invalid for the consumer and we shouldn't make decisions based on invalid register class either.

I'm not comfortable with creating registers with a class that is only valid for the producer. Why do you think fixing the register class by emitting a COPY is better left to instruction selector?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why do you think fixing the register class by emitting a COPY is better left to instruction selector?

I don't, ideally tablegen would fully understand the set of instructions that need to be emitted here and explicitly handle it. But as far as a hack to make progress goes, I think that's better than using incomplete registers if it's hard to get tablegen into a state where that is possible

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'll try to do that at tablegen level. The changes are going to be non-local and I'll probably need to split them into several smaller patches; I'll keep this one as a draft.

MRI.noteNewVirtualRegister(Reg);
State.TempRegisters[TempRegID] = Reg;
DEBUG_WITH_TYPE(TgtExecutor::getName(), {
dbgs() << CurrentIdx << ": TempRegs[" << TempRegID
<< "] = GIR_MakeVirtualTempReg()\n";
});
break;
}
case GIR_ReplaceReg: {
Expand Down
5 changes: 1 addition & 4 deletions llvm/lib/CodeGen/TargetRegisterInfo.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -175,11 +175,8 @@ Printable printRegClassOrBank(Register Reg, const MachineRegisterInfo &RegInfo,
OS << StringRef(TRI->getRegClassName(RegInfo.getRegClass(Reg))).lower();
else if (RegInfo.getRegBankOrNull(Reg))
OS << StringRef(RegInfo.getRegBankOrNull(Reg)->getName()).lower();
else {
else
OS << "_";
assert((RegInfo.def_empty(Reg) || RegInfo.getType(Reg).isValid()) &&
"Generic registers must have a valid type");
}
});
}

Expand Down
72 changes: 36 additions & 36 deletions llvm/test/CodeGen/AMDGPU/GlobalISel/inst-select-fneg.mir
Original file line number Diff line number Diff line change
Expand Up @@ -679,35 +679,35 @@ body: |
; SI-NEXT: {{ $}}
; SI-NEXT: [[COPY:%[0-9]+]]:sgpr(s32) = COPY $sgpr0
; SI-NEXT: [[FABS:%[0-9]+]]:vgpr_32(s32) = G_FABS [[COPY]]
; SI-NEXT: [[S_MOV_B32_:%[0-9]+]]:sreg_32(s16) = S_MOV_B32 2147483648
; SI-NEXT: [[V_XOR_B32_e64_:%[0-9]+]]:vgpr_32(s32) = V_XOR_B32_e64 [[S_MOV_B32_]](s16), [[FABS]](s32), implicit $exec
; SI-NEXT: [[S_MOV_B32_:%[0-9]+]]:sreg_32 = S_MOV_B32 2147483648
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This change is somehow related to G_FABS not being selected. I didn't dig deep.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The output is the same, the type is just dropped?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The output is the same, the type is just dropped?

Yes. I'll analyze it further.

; SI-NEXT: [[V_XOR_B32_e64_:%[0-9]+]]:vgpr_32(s32) = V_XOR_B32_e64 [[S_MOV_B32_]], [[FABS]](s32), implicit $exec
; SI-NEXT: S_ENDPGM 0, implicit [[V_XOR_B32_e64_]](s32)
;
; VI-LABEL: name: fneg_fabs_s32_vs
; VI: liveins: $sgpr0
; VI-NEXT: {{ $}}
; VI-NEXT: [[COPY:%[0-9]+]]:sgpr(s32) = COPY $sgpr0
; VI-NEXT: [[FABS:%[0-9]+]]:vgpr_32(s32) = G_FABS [[COPY]]
; VI-NEXT: [[S_MOV_B32_:%[0-9]+]]:sreg_32(s16) = S_MOV_B32 2147483648
; VI-NEXT: [[V_XOR_B32_e64_:%[0-9]+]]:vgpr_32(s32) = V_XOR_B32_e64 [[S_MOV_B32_]](s16), [[FABS]](s32), implicit $exec
; VI-NEXT: [[S_MOV_B32_:%[0-9]+]]:sreg_32 = S_MOV_B32 2147483648
; VI-NEXT: [[V_XOR_B32_e64_:%[0-9]+]]:vgpr_32(s32) = V_XOR_B32_e64 [[S_MOV_B32_]], [[FABS]](s32), implicit $exec
; VI-NEXT: S_ENDPGM 0, implicit [[V_XOR_B32_e64_]](s32)
;
; GFX9-LABEL: name: fneg_fabs_s32_vs
; GFX9: liveins: $sgpr0
; GFX9-NEXT: {{ $}}
; GFX9-NEXT: [[COPY:%[0-9]+]]:sgpr(s32) = COPY $sgpr0
; GFX9-NEXT: [[FABS:%[0-9]+]]:vgpr_32(s32) = G_FABS [[COPY]]
; GFX9-NEXT: [[S_MOV_B32_:%[0-9]+]]:sreg_32(s16) = S_MOV_B32 2147483648
; GFX9-NEXT: [[V_XOR_B32_e64_:%[0-9]+]]:vgpr_32(s32) = V_XOR_B32_e64 [[S_MOV_B32_]](s16), [[FABS]](s32), implicit $exec
; GFX9-NEXT: [[S_MOV_B32_:%[0-9]+]]:sreg_32 = S_MOV_B32 2147483648
; GFX9-NEXT: [[V_XOR_B32_e64_:%[0-9]+]]:vgpr_32(s32) = V_XOR_B32_e64 [[S_MOV_B32_]], [[FABS]](s32), implicit $exec
; GFX9-NEXT: S_ENDPGM 0, implicit [[V_XOR_B32_e64_]](s32)
;
; GFX10-LABEL: name: fneg_fabs_s32_vs
; GFX10: liveins: $sgpr0
; GFX10-NEXT: {{ $}}
; GFX10-NEXT: [[COPY:%[0-9]+]]:sgpr(s32) = COPY $sgpr0
; GFX10-NEXT: [[FABS:%[0-9]+]]:vgpr_32(s32) = G_FABS [[COPY]]
; GFX10-NEXT: [[S_MOV_B32_:%[0-9]+]]:sreg_32(s16) = S_MOV_B32 2147483648
; GFX10-NEXT: [[V_XOR_B32_e64_:%[0-9]+]]:vgpr_32(s32) = V_XOR_B32_e64 [[S_MOV_B32_]](s16), [[FABS]](s32), implicit $exec
; GFX10-NEXT: [[S_MOV_B32_:%[0-9]+]]:sreg_32 = S_MOV_B32 2147483648
; GFX10-NEXT: [[V_XOR_B32_e64_:%[0-9]+]]:vgpr_32(s32) = V_XOR_B32_e64 [[S_MOV_B32_]], [[FABS]](s32), implicit $exec
; GFX10-NEXT: S_ENDPGM 0, implicit [[V_XOR_B32_e64_]](s32)
%0:sgpr(s32) = COPY $sgpr0
%1:vgpr(s32) = G_FABS %0
Expand Down Expand Up @@ -978,35 +978,35 @@ body: |
; SI-NEXT: {{ $}}
; SI-NEXT: [[COPY:%[0-9]+]]:sgpr(<2 x s16>) = COPY $sgpr0
; SI-NEXT: [[FABS:%[0-9]+]]:vgpr_32(<2 x s16>) = G_FABS [[COPY]]
; SI-NEXT: [[S_MOV_B32_:%[0-9]+]]:sreg_32(s16) = S_MOV_B32 2147516416
; SI-NEXT: [[V_XOR_B32_e64_:%[0-9]+]]:vgpr_32(<2 x s16>) = V_XOR_B32_e64 [[S_MOV_B32_]](s16), [[FABS]](<2 x s16>), implicit $exec
; SI-NEXT: [[S_MOV_B32_:%[0-9]+]]:sreg_32 = S_MOV_B32 2147516416
; SI-NEXT: [[V_XOR_B32_e64_:%[0-9]+]]:vgpr_32(<2 x s16>) = V_XOR_B32_e64 [[S_MOV_B32_]], [[FABS]](<2 x s16>), implicit $exec
; SI-NEXT: $vgpr0 = COPY [[V_XOR_B32_e64_]](<2 x s16>)
;
; VI-LABEL: name: fneg_fabs_v2s16_vs
; VI: liveins: $sgpr0
; VI-NEXT: {{ $}}
; VI-NEXT: [[COPY:%[0-9]+]]:sgpr(<2 x s16>) = COPY $sgpr0
; VI-NEXT: [[FABS:%[0-9]+]]:vgpr_32(<2 x s16>) = G_FABS [[COPY]]
; VI-NEXT: [[S_MOV_B32_:%[0-9]+]]:sreg_32(s16) = S_MOV_B32 2147516416
; VI-NEXT: [[V_XOR_B32_e64_:%[0-9]+]]:vgpr_32(<2 x s16>) = V_XOR_B32_e64 [[S_MOV_B32_]](s16), [[FABS]](<2 x s16>), implicit $exec
; VI-NEXT: [[S_MOV_B32_:%[0-9]+]]:sreg_32 = S_MOV_B32 2147516416
; VI-NEXT: [[V_XOR_B32_e64_:%[0-9]+]]:vgpr_32(<2 x s16>) = V_XOR_B32_e64 [[S_MOV_B32_]], [[FABS]](<2 x s16>), implicit $exec
; VI-NEXT: $vgpr0 = COPY [[V_XOR_B32_e64_]](<2 x s16>)
;
; GFX9-LABEL: name: fneg_fabs_v2s16_vs
; GFX9: liveins: $sgpr0
; GFX9-NEXT: {{ $}}
; GFX9-NEXT: [[COPY:%[0-9]+]]:sgpr(<2 x s16>) = COPY $sgpr0
; GFX9-NEXT: [[FABS:%[0-9]+]]:vgpr_32(<2 x s16>) = G_FABS [[COPY]]
; GFX9-NEXT: [[S_MOV_B32_:%[0-9]+]]:sreg_32(s16) = S_MOV_B32 2147516416
; GFX9-NEXT: [[V_XOR_B32_e64_:%[0-9]+]]:vgpr_32(<2 x s16>) = V_XOR_B32_e64 [[S_MOV_B32_]](s16), [[FABS]](<2 x s16>), implicit $exec
; GFX9-NEXT: [[S_MOV_B32_:%[0-9]+]]:sreg_32 = S_MOV_B32 2147516416
; GFX9-NEXT: [[V_XOR_B32_e64_:%[0-9]+]]:vgpr_32(<2 x s16>) = V_XOR_B32_e64 [[S_MOV_B32_]], [[FABS]](<2 x s16>), implicit $exec
; GFX9-NEXT: $vgpr0 = COPY [[V_XOR_B32_e64_]](<2 x s16>)
;
; GFX10-LABEL: name: fneg_fabs_v2s16_vs
; GFX10: liveins: $sgpr0
; GFX10-NEXT: {{ $}}
; GFX10-NEXT: [[COPY:%[0-9]+]]:sgpr(<2 x s16>) = COPY $sgpr0
; GFX10-NEXT: [[FABS:%[0-9]+]]:vgpr_32(<2 x s16>) = G_FABS [[COPY]]
; GFX10-NEXT: [[S_MOV_B32_:%[0-9]+]]:sreg_32(s16) = S_MOV_B32 2147516416
; GFX10-NEXT: [[V_XOR_B32_e64_:%[0-9]+]]:vgpr_32(<2 x s16>) = V_XOR_B32_e64 [[S_MOV_B32_]](s16), [[FABS]](<2 x s16>), implicit $exec
; GFX10-NEXT: [[S_MOV_B32_:%[0-9]+]]:sreg_32 = S_MOV_B32 2147516416
; GFX10-NEXT: [[V_XOR_B32_e64_:%[0-9]+]]:vgpr_32(<2 x s16>) = V_XOR_B32_e64 [[S_MOV_B32_]], [[FABS]](<2 x s16>), implicit $exec
; GFX10-NEXT: $vgpr0 = COPY [[V_XOR_B32_e64_]](<2 x s16>)
%0:sgpr(<2 x s16>) = COPY $sgpr0
%1:vgpr(<2 x s16>) = G_FABS %0
Expand Down Expand Up @@ -1148,47 +1148,47 @@ body: |
; SI-NEXT: {{ $}}
; SI-NEXT: [[COPY:%[0-9]+]]:sgpr(s64) = COPY $sgpr0_sgpr1
; SI-NEXT: [[FABS:%[0-9]+]]:vreg_64(s64) = G_FABS [[COPY]]
; SI-NEXT: [[COPY1:%[0-9]+]]:vgpr_32(s32) = COPY [[FABS]].sub1(s64)
; SI-NEXT: [[S_MOV_B32_:%[0-9]+]]:sreg_32(s32) = S_MOV_B32 2147483648
; SI-NEXT: [[V_XOR_B32_e64_:%[0-9]+]]:vgpr_32(s16) = V_XOR_B32_e64 [[S_MOV_B32_]](s32), [[COPY1]](s32), implicit $exec
; SI-NEXT: [[COPY2:%[0-9]+]]:vgpr_32(s32) = COPY [[FABS]].sub0(s64)
; SI-NEXT: [[REG_SEQUENCE:%[0-9]+]]:vreg_64(s64) = REG_SEQUENCE [[COPY2]](s32), %subreg.sub0, [[V_XOR_B32_e64_]](s16), %subreg.sub1
; SI-NEXT: [[COPY1:%[0-9]+]]:vgpr_32 = COPY [[FABS]].sub1(s64)
; SI-NEXT: [[S_MOV_B32_:%[0-9]+]]:sreg_32 = S_MOV_B32 2147483648
; SI-NEXT: [[V_XOR_B32_e64_:%[0-9]+]]:vgpr_32 = V_XOR_B32_e64 [[S_MOV_B32_]], [[COPY1]], implicit $exec
; SI-NEXT: [[COPY2:%[0-9]+]]:vgpr_32 = COPY [[FABS]].sub0(s64)
; SI-NEXT: [[REG_SEQUENCE:%[0-9]+]]:vreg_64(s64) = REG_SEQUENCE [[COPY2]], %subreg.sub0, [[V_XOR_B32_e64_]], %subreg.sub1
; SI-NEXT: S_ENDPGM 0, implicit [[REG_SEQUENCE]](s64)
;
; VI-LABEL: name: fneg_fabs_s64_vs
; VI: liveins: $sgpr0_sgpr1
; VI-NEXT: {{ $}}
; VI-NEXT: [[COPY:%[0-9]+]]:sgpr(s64) = COPY $sgpr0_sgpr1
; VI-NEXT: [[FABS:%[0-9]+]]:vreg_64(s64) = G_FABS [[COPY]]
; VI-NEXT: [[COPY1:%[0-9]+]]:vgpr_32(s32) = COPY [[FABS]].sub1(s64)
; VI-NEXT: [[S_MOV_B32_:%[0-9]+]]:sreg_32(s32) = S_MOV_B32 2147483648
; VI-NEXT: [[V_XOR_B32_e64_:%[0-9]+]]:vgpr_32(s16) = V_XOR_B32_e64 [[S_MOV_B32_]](s32), [[COPY1]](s32), implicit $exec
; VI-NEXT: [[COPY2:%[0-9]+]]:vgpr_32(s32) = COPY [[FABS]].sub0(s64)
; VI-NEXT: [[REG_SEQUENCE:%[0-9]+]]:vreg_64(s64) = REG_SEQUENCE [[COPY2]](s32), %subreg.sub0, [[V_XOR_B32_e64_]](s16), %subreg.sub1
; VI-NEXT: [[COPY1:%[0-9]+]]:vgpr_32 = COPY [[FABS]].sub1(s64)
; VI-NEXT: [[S_MOV_B32_:%[0-9]+]]:sreg_32 = S_MOV_B32 2147483648
; VI-NEXT: [[V_XOR_B32_e64_:%[0-9]+]]:vgpr_32 = V_XOR_B32_e64 [[S_MOV_B32_]], [[COPY1]], implicit $exec
; VI-NEXT: [[COPY2:%[0-9]+]]:vgpr_32 = COPY [[FABS]].sub0(s64)
; VI-NEXT: [[REG_SEQUENCE:%[0-9]+]]:vreg_64(s64) = REG_SEQUENCE [[COPY2]], %subreg.sub0, [[V_XOR_B32_e64_]], %subreg.sub1
; VI-NEXT: S_ENDPGM 0, implicit [[REG_SEQUENCE]](s64)
;
; GFX9-LABEL: name: fneg_fabs_s64_vs
; GFX9: liveins: $sgpr0_sgpr1
; GFX9-NEXT: {{ $}}
; GFX9-NEXT: [[COPY:%[0-9]+]]:sgpr(s64) = COPY $sgpr0_sgpr1
; GFX9-NEXT: [[FABS:%[0-9]+]]:vreg_64(s64) = G_FABS [[COPY]]
; GFX9-NEXT: [[COPY1:%[0-9]+]]:vgpr_32(s32) = COPY [[FABS]].sub1(s64)
; GFX9-NEXT: [[S_MOV_B32_:%[0-9]+]]:sreg_32(s32) = S_MOV_B32 2147483648
; GFX9-NEXT: [[V_XOR_B32_e64_:%[0-9]+]]:vgpr_32(s16) = V_XOR_B32_e64 [[S_MOV_B32_]](s32), [[COPY1]](s32), implicit $exec
; GFX9-NEXT: [[COPY2:%[0-9]+]]:vgpr_32(s32) = COPY [[FABS]].sub0(s64)
; GFX9-NEXT: [[REG_SEQUENCE:%[0-9]+]]:vreg_64(s64) = REG_SEQUENCE [[COPY2]](s32), %subreg.sub0, [[V_XOR_B32_e64_]](s16), %subreg.sub1
; GFX9-NEXT: [[COPY1:%[0-9]+]]:vgpr_32 = COPY [[FABS]].sub1(s64)
; GFX9-NEXT: [[S_MOV_B32_:%[0-9]+]]:sreg_32 = S_MOV_B32 2147483648
; GFX9-NEXT: [[V_XOR_B32_e64_:%[0-9]+]]:vgpr_32 = V_XOR_B32_e64 [[S_MOV_B32_]], [[COPY1]], implicit $exec
; GFX9-NEXT: [[COPY2:%[0-9]+]]:vgpr_32 = COPY [[FABS]].sub0(s64)
; GFX9-NEXT: [[REG_SEQUENCE:%[0-9]+]]:vreg_64(s64) = REG_SEQUENCE [[COPY2]], %subreg.sub0, [[V_XOR_B32_e64_]], %subreg.sub1
; GFX9-NEXT: S_ENDPGM 0, implicit [[REG_SEQUENCE]](s64)
;
; GFX10-LABEL: name: fneg_fabs_s64_vs
; GFX10: liveins: $sgpr0_sgpr1
; GFX10-NEXT: {{ $}}
; GFX10-NEXT: [[COPY:%[0-9]+]]:sgpr(s64) = COPY $sgpr0_sgpr1
; GFX10-NEXT: [[FABS:%[0-9]+]]:vreg_64(s64) = G_FABS [[COPY]]
; GFX10-NEXT: [[COPY1:%[0-9]+]]:vgpr_32(s32) = COPY [[FABS]].sub1(s64)
; GFX10-NEXT: [[S_MOV_B32_:%[0-9]+]]:sreg_32(s32) = S_MOV_B32 2147483648
; GFX10-NEXT: [[V_XOR_B32_e64_:%[0-9]+]]:vgpr_32(s16) = V_XOR_B32_e64 [[S_MOV_B32_]](s32), [[COPY1]](s32), implicit $exec
; GFX10-NEXT: [[COPY2:%[0-9]+]]:vgpr_32(s32) = COPY [[FABS]].sub0(s64)
; GFX10-NEXT: [[REG_SEQUENCE:%[0-9]+]]:vreg_64(s64) = REG_SEQUENCE [[COPY2]](s32), %subreg.sub0, [[V_XOR_B32_e64_]](s16), %subreg.sub1
; GFX10-NEXT: [[COPY1:%[0-9]+]]:vgpr_32 = COPY [[FABS]].sub1(s64)
; GFX10-NEXT: [[S_MOV_B32_:%[0-9]+]]:sreg_32 = S_MOV_B32 2147483648
; GFX10-NEXT: [[V_XOR_B32_e64_:%[0-9]+]]:vgpr_32 = V_XOR_B32_e64 [[S_MOV_B32_]], [[COPY1]], implicit $exec
; GFX10-NEXT: [[COPY2:%[0-9]+]]:vgpr_32 = COPY [[FABS]].sub0(s64)
; GFX10-NEXT: [[REG_SEQUENCE:%[0-9]+]]:vreg_64(s64) = REG_SEQUENCE [[COPY2]], %subreg.sub0, [[V_XOR_B32_e64_]], %subreg.sub1
; GFX10-NEXT: S_ENDPGM 0, implicit [[REG_SEQUENCE]](s64)
%0:sgpr(s64) = COPY $sgpr0_sgpr1
%1:vgpr(s64) = G_FABS %0
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ def MyCombiner: GICombiner<"GenMyCombiner", [
// CHECK-NEXT: // MIs[1] y
// CHECK-NEXT: // No operand predicates
// CHECK-NEXT: GIM_CheckIsSafeToFold, /*NumInsns*/1,
// CHECK-NEXT: GIR_MakeTempReg, /*TempRegID*/0, /*TypeID*/GILLT_s32,
// CHECK-NEXT: GIR_MakeGenericTempReg, /*TempRegID*/0, /*TypeID*/GILLT_s32,
// CHECK-NEXT: // Combiner Rule #1: ReplaceTemp
// CHECK-NEXT: GIR_BuildRootMI, /*Opcode*/GIMT_Encode2(TargetOpcode::G_UNMERGE_VALUES),
// CHECK-NEXT: GIR_RootToRootCopy, /*OpIdx*/0, // a
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -73,7 +73,7 @@ def MyCombiner: GICombiner<"GenMyCombiner", [
// CHECK-NEXT: // No operand predicates
// CHECK-NEXT: // MIs[0] Operand 1
// CHECK-NEXT: GIM_CheckConstantInt8, /*MI*/0, /*Op*/1, 0,
// CHECK-NEXT: GIR_MakeTempReg, /*TempRegID*/0, /*TypeID*/GILLT_s32,
// CHECK-NEXT: GIR_MakeGenericTempReg, /*TempRegID*/0, /*TypeID*/GILLT_s32,
// CHECK-NEXT: GIR_BuildConstant, /*TempRegID*/0, /*Val*/GIMT_Encode8(0),
// CHECK-NEXT: // Combiner Rule #1: InstTest1
// CHECK-NEXT: GIR_BuildRootMI, /*Opcode*/GIMT_Encode2(TargetOpcode::COPY),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ def MyCombiner: GICombiner<"GenMyCombiner", [
// CHECK-NEXT: // No operand predicates
// CHECK-NEXT: // MIs[0] Operand 2
// CHECK-NEXT: GIM_CheckConstantInt8, /*MI*/0, /*Op*/2, 0,
// CHECK-NEXT: GIR_MakeTempReg, /*TempRegID*/0, /*TypeID*/GILLT_s32,
// CHECK-NEXT: GIR_MakeGenericTempReg, /*TempRegID*/0, /*TypeID*/GILLT_s32,
// CHECK-NEXT: // Combiner Rule #0: IntrinTest0
// CHECK-NEXT: GIR_BuildRootMI, /*Opcode*/GIMT_Encode2(TargetOpcode::G_INTRINSIC),
// CHECK-NEXT: GIR_AddTempRegister, /*InsnID*/0, /*TempRegID*/0, /*TempRegFlags*/GIMT_Encode2(RegState::Define),
Expand All @@ -62,7 +62,7 @@ def MyCombiner: GICombiner<"GenMyCombiner", [
// CHECK-NEXT: // No operand predicates
// CHECK-NEXT: // MIs[0] b
// CHECK-NEXT: // No operand predicates
// CHECK-NEXT: GIR_MakeTempReg, /*TempRegID*/0, /*TypeID*/GILLT_s32,
// CHECK-NEXT: GIR_MakeGenericTempReg, /*TempRegID*/0, /*TypeID*/GILLT_s32,
// CHECK-NEXT: // Combiner Rule #1: SpecialIntrins
// CHECK-NEXT: GIR_BuildRootMI, /*Opcode*/GIMT_Encode2(TargetOpcode::G_INTRINSIC_CONVERGENT),
// CHECK-NEXT: GIR_AddTempRegister, /*InsnID*/0, /*TempRegID*/0, /*TempRegFlags*/GIMT_Encode2(RegState::Define),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ def MyCombiner: GICombiner<"GenMyCombiner", [
// CHECK-NEXT: // MIs[1] b
// CHECK-NEXT: GIM_CheckIsSameOperandIgnoreCopies, /*MI*/1, /*OpIdx*/1, /*OtherMI*/0, /*OtherOpIdx*/1,
// CHECK-NEXT: GIM_CheckIsSafeToFold, /*NumInsns*/1,
// CHECK-NEXT: GIR_MakeTempReg, /*TempRegID*/0, /*TypeID*/GILLT_s64,
// CHECK-NEXT: GIR_MakeGenericTempReg, /*TempRegID*/0, /*TypeID*/GILLT_s64,
// CHECK-NEXT: // Combiner Rule #0: InstTest0
// CHECK-NEXT: GIR_BuildRootMI, /*Opcode*/GIMT_Encode2(TargetOpcode::G_ADD),
// CHECK-NEXT: GIR_AddTempRegister, /*InsnID*/0, /*TempRegID*/0, /*TempRegFlags*/GIMT_Encode2(RegState::Define),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ def MyCombiner: GICombiner<"GenMyCombiner", [
// CHECK-NEXT: // No operand predicates
// CHECK-NEXT: // MIs[0] __Test0_match_0.z
// CHECK-NEXT: // No operand predicates
// CHECK-NEXT: GIR_MakeTempReg, /*TempRegID*/0, /*TypeID*/GILLT_s32,
// CHECK-NEXT: GIR_MakeGenericTempReg, /*TempRegID*/0, /*TypeID*/GILLT_s32,
// CHECK-NEXT: GIR_BuildConstant, /*TempRegID*/0, /*Val*/GIMT_Encode8(0),
// CHECK-NEXT: // Combiner Rule #0: Test0 @ [__Test0_match_0[1]]
// CHECK-NEXT: GIR_BuildRootMI, /*Opcode*/GIMT_Encode2(TargetOpcode::COPY),
Expand All @@ -59,7 +59,7 @@ def MyCombiner: GICombiner<"GenMyCombiner", [
// CHECK-NEXT: // MIs[1] __Test0_match_0.x
// CHECK-NEXT: // No operand predicates
// CHECK-NEXT: GIM_CheckIsSafeToFold, /*NumInsns*/1,
// CHECK-NEXT: GIR_MakeTempReg, /*TempRegID*/0, /*TypeID*/GILLT_s32,
// CHECK-NEXT: GIR_MakeGenericTempReg, /*TempRegID*/0, /*TypeID*/GILLT_s32,
// CHECK-NEXT: GIR_BuildConstant, /*TempRegID*/0, /*Val*/GIMT_Encode8(0),
// CHECK-NEXT: // Combiner Rule #0: Test0 @ [__Test0_match_0[0]]
// CHECK-NEXT: GIR_BuildRootMI, /*Opcode*/GIMT_Encode2(TargetOpcode::COPY),
Expand All @@ -75,7 +75,7 @@ def MyCombiner: GICombiner<"GenMyCombiner", [
// CHECK-NEXT: // No operand predicates
// CHECK-NEXT: // MIs[0] __Test0_match_0.z
// CHECK-NEXT: // No operand predicates
// CHECK-NEXT: GIR_MakeTempReg, /*TempRegID*/0, /*TypeID*/GILLT_s32,
// CHECK-NEXT: GIR_MakeGenericTempReg, /*TempRegID*/0, /*TypeID*/GILLT_s32,
// CHECK-NEXT: GIR_BuildConstant, /*TempRegID*/0, /*Val*/GIMT_Encode8(0),
// CHECK-NEXT: // Combiner Rule #0: Test0 @ [__Test0_match_0[2]]
// CHECK-NEXT: GIR_BuildRootMI, /*Opcode*/GIMT_Encode2(TargetOpcode::COPY),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,9 +25,9 @@ def Test0 : GICombineRule<
// CHECK-NEXT: GIM_RecordRegType, /*MI*/0, /*Op*/1, /*TempTypeIdx*/uint8_t(-2),
// CHECK-NEXT: // MIs[0] Operand 2
// CHECK-NEXT: GIM_CheckConstantInt8, /*MI*/0, /*Op*/2, uint8_t(-1),
// CHECK-NEXT: GIR_MakeTempReg, /*TempRegID*/1, /*TypeID*/uint8_t(-2),
// CHECK-NEXT: GIR_MakeGenericTempReg, /*TempRegID*/1, /*TypeID*/uint8_t(-2),
// CHECK-NEXT: GIR_BuildConstant, /*TempRegID*/1, /*Val*/GIMT_Encode8(0),
// CHECK-NEXT: GIR_MakeTempReg, /*TempRegID*/0, /*TypeID*/uint8_t(-1),
// CHECK-NEXT: GIR_MakeGenericTempReg, /*TempRegID*/0, /*TypeID*/uint8_t(-1),
// CHECK-NEXT: // Combiner Rule #0: Test0
// CHECK-NEXT: GIR_BuildRootMI, /*Opcode*/GIMT_Encode2(TargetOpcode::G_CONSTANT),
// CHECK-NEXT: GIR_AddTempRegister, /*InsnID*/0, /*TempRegID*/0, /*TempRegFlags*/GIMT_Encode2(RegState::Define),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -237,7 +237,7 @@ def MyCombiner: GICombiner<"GenMyCombiner", [
// CHECK-NEXT: // MIs[0] cst
// CHECK-NEXT: // No operand predicates
// CHECK-NEXT: GIM_CheckCxxInsnPredicate, /*MI*/0, /*FnId*/GIMT_Encode2(GICXXPred_MI_Predicate_GICombiner0),
// CHECK-NEXT: GIR_MakeTempReg, /*TempRegID*/0, /*TypeID*/GILLT_s32,
// CHECK-NEXT: GIR_MakeGenericTempReg, /*TempRegID*/0, /*TypeID*/GILLT_s32,
// CHECK-NEXT: GIR_BuildConstant, /*TempRegID*/0, /*Val*/GIMT_Encode8(0),
// CHECK-NEXT: // Combiner Rule #6: PatFragTest0 @ [__PatFragTest0_match_1[0]]
// CHECK-NEXT: GIR_BuildRootMI, /*Opcode*/GIMT_Encode2(TargetOpcode::COPY),
Expand Down
Loading
Loading