From 1adfb58fa1bbaebb8acd17fbe578315d4f794090 Mon Sep 17 00:00:00 2001 From: Matt Arsenault Date: Mon, 1 Jul 2019 15:39:27 +0000 Subject: [PATCH] AMDGPU/GlobalISel: Select G_BRCOND for scc conditions git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@364786 91177308-0d34-0410-b5e6-96231b3b80d8 --- .../AMDGPU/AMDGPUInstructionSelector.cpp | 33 ++++ lib/Target/AMDGPU/AMDGPUInstructionSelector.h | 1 + .../AMDGPU/GlobalISel/inst-select-br.mir | 21 +++ .../AMDGPU/GlobalISel/inst-select-brcond.mir | 173 ++++++++++++++++++ 4 files changed, 228 insertions(+) create mode 100644 test/CodeGen/AMDGPU/GlobalISel/inst-select-br.mir create mode 100644 test/CodeGen/AMDGPU/GlobalISel/inst-select-brcond.mir diff --git a/lib/Target/AMDGPU/AMDGPUInstructionSelector.cpp b/lib/Target/AMDGPU/AMDGPUInstructionSelector.cpp index 7ea1a67efec..666df1c019f 100644 --- a/lib/Target/AMDGPU/AMDGPUInstructionSelector.cpp +++ b/lib/Target/AMDGPU/AMDGPUInstructionSelector.cpp @@ -981,6 +981,37 @@ bool AMDGPUInstructionSelector::selectG_LOAD(MachineInstr &I) const { return Ret; } +bool AMDGPUInstructionSelector::selectG_BRCOND(MachineInstr &I) const { + MachineBasicBlock *BB = I.getParent(); + MachineFunction *MF = BB->getParent(); + MachineRegisterInfo &MRI = MF->getRegInfo(); + MachineOperand &CondOp = I.getOperand(0); + Register CondReg = CondOp.getReg(); + const DebugLoc &DL = I.getDebugLoc(); + + if (isSCC(CondReg, MRI)) { + // In SelectionDAG, we inspect the IR block for uniformity metadata to decide + // whether the branch is uniform when selecting the instruction. In + // GlobalISel, we should push that decision into RegBankSelect. Assume for now + // RegBankSelect knows what it's doing if the branch condition is scc, even + // though it currently does not. + BuildMI(*BB, &I, DL, TII.get(AMDGPU::COPY), AMDGPU::SCC) + .addReg(CondReg); + if (!MRI.getRegClassOrNull(CondReg)) { + const TargetRegisterClass *RC + = TRI.getConstrainedRegClassForOperand(CondOp, MRI); + MRI.setRegClass(CondReg, RC); + } + + BuildMI(*BB, &I, DL, TII.get(AMDGPU::S_CBRANCH_SCC1)) + .addMBB(I.getOperand(1).getMBB()); + I.eraseFromParent(); + return true; + } + + return false; +} + bool AMDGPUInstructionSelector::select(MachineInstr &I, CodeGenCoverage &CoverageInfo) const { @@ -1036,6 +1067,8 @@ bool AMDGPUInstructionSelector::select(MachineInstr &I, } return false; + case TargetOpcode::G_BRCOND: + return selectG_BRCOND(I); } return false; } diff --git a/lib/Target/AMDGPU/AMDGPUInstructionSelector.h b/lib/Target/AMDGPU/AMDGPUInstructionSelector.h index 0631183fe9d..572710fc106 100644 --- a/lib/Target/AMDGPU/AMDGPUInstructionSelector.h +++ b/lib/Target/AMDGPU/AMDGPUInstructionSelector.h @@ -84,6 +84,7 @@ private: bool selectG_LOAD(MachineInstr &I) const; bool selectG_SELECT(MachineInstr &I) const; bool selectG_STORE(MachineInstr &I) const; + bool selectG_BRCOND(MachineInstr &I) const; std::pair selectVOP3ModsImpl(Register Src, const MachineRegisterInfo &MRI) const; diff --git a/test/CodeGen/AMDGPU/GlobalISel/inst-select-br.mir b/test/CodeGen/AMDGPU/GlobalISel/inst-select-br.mir new file mode 100644 index 00000000000..70f67433f78 --- /dev/null +++ b/test/CodeGen/AMDGPU/GlobalISel/inst-select-br.mir @@ -0,0 +1,21 @@ +# NOTE: Assertions have been autogenerated by utils/update_mir_test_checks.py +# RUN: llc -march=amdgcn -run-pass=instruction-select -verify-machineinstrs %s -o - | FileCheck %s -check-prefixes=GCN + +--- + +name: br +legalized: true +regBankSelected: true + +body: | + ; GCN-LABEL: name: br + ; GCN: bb.0: + ; GCN: successors: %bb.1(0x80000000) + ; GCN: S_BRANCH %bb.1 + ; GCN: bb.1: + bb.0: + G_BR %bb.1 + + bb.1: + +... diff --git a/test/CodeGen/AMDGPU/GlobalISel/inst-select-brcond.mir b/test/CodeGen/AMDGPU/GlobalISel/inst-select-brcond.mir new file mode 100644 index 00000000000..33c052ba093 --- /dev/null +++ b/test/CodeGen/AMDGPU/GlobalISel/inst-select-brcond.mir @@ -0,0 +1,173 @@ +# NOTE: Assertions have been autogenerated by utils/update_mir_test_checks.py +# RUN: llc -march=amdgcn -run-pass=instruction-select -global-isel-abort=2 -pass-remarks-missed='gisel*' -verify-machineinstrs %s -o - 2> %t | FileCheck -check-prefixes=GCN %s +# RUN: FileCheck -check-prefix=ERR %s < %t + +# ERR-NOT: remark: +# ERR: remark: :0:0: cannot select: G_BRCOND %1:sgpr(s1), %bb.1 (in function: brcond_sgpr) +# ERR-NEXT: remark: :0:0: cannot select: G_BRCOND %2:vcc(s1), %bb.1 (in function: brcond_vcc) +# ERR-NOT: remark: + +--- + +name: brcond_scc +legalized: true +regBankSelected: true + +body: | + ; GCN-LABEL: name: brcond_scc + ; GCN: bb.0: + ; GCN: successors: %bb.1(0x80000000) + ; GCN: [[COPY:%[0-9]+]]:sreg_32 = COPY $sgpr0 + ; GCN: [[COPY1:%[0-9]+]]:sreg_32 = COPY $sgpr1 + ; GCN: S_CMP_EQ_U32 [[COPY]], [[COPY1]], implicit-def $scc + ; GCN: [[COPY2:%[0-9]+]]:sreg_32_xm0 = COPY $scc + ; GCN: $scc = COPY [[COPY2]] + ; GCN: S_CBRANCH_SCC1 %bb.1, implicit $scc + ; GCN: bb.1: + bb.0: + liveins: $sgpr0, $sgpr1 + + %0:sgpr(s32) = COPY $sgpr0 + %1:sgpr(s32) = COPY $sgpr1 + %2:scc(s1) = G_ICMP intpred(eq), %0, %1 + G_BRCOND %2, %bb.1 + + bb.1: + +... + +--- + +name: brcond_scc_impdef +legalized: true +regBankSelected: true + +body: | + ; GCN-LABEL: name: brcond_scc_impdef + ; GCN: bb.0: + ; GCN: successors: %bb.1(0x80000000) + ; GCN: [[DEF:%[0-9]+]]:sreg_32_xm0 = IMPLICIT_DEF + ; GCN: $scc = COPY [[DEF]] + ; GCN: S_CBRANCH_SCC1 %bb.1, implicit $scc + ; GCN: bb.1: + bb.0: + liveins: $sgpr0, $sgpr1 + + %0:scc(s1) = G_IMPLICIT_DEF + G_BRCOND %0, %bb.1 + + bb.1: + +... + +--- + +name: brcond_scc_undef +legalized: true +regBankSelected: true + +body: | + ; GCN-LABEL: name: brcond_scc_undef + ; GCN: bb.0: + ; GCN: successors: %bb.1(0x80000000) + ; GCN: $scc = COPY %0:sreg_32_xm0 + ; GCN: S_CBRANCH_SCC1 %bb.1, implicit $scc + ; GCN: bb.1: + bb.0: + liveins: $sgpr0, $sgpr1 + + G_BRCOND undef %0:scc(s1), %bb.1 + + bb.1: + +... + +--- + +name: brcond_scc_br +legalized: true +regBankSelected: true + +body: | + ; GCN-LABEL: name: brcond_scc_br + ; GCN: bb.0: + ; GCN: successors: %bb.1(0x80000000) + ; GCN: [[COPY:%[0-9]+]]:sreg_32 = COPY $sgpr0 + ; GCN: [[COPY1:%[0-9]+]]:sreg_32 = COPY $sgpr1 + ; GCN: S_CMP_EQ_U32 [[COPY]], [[COPY1]], implicit-def $scc + ; GCN: [[COPY2:%[0-9]+]]:sreg_32_xm0 = COPY $scc + ; GCN: $scc = COPY [[COPY2]] + ; GCN: S_CBRANCH_SCC1 %bb.1, implicit $scc + ; GCN: S_BRANCH %bb.1 + ; GCN: bb.1: + ; GCN: successors: %bb.2(0x80000000) + ; GCN: bb.2: + bb.0: + liveins: $sgpr0, $sgpr1 + + %0:sgpr(s32) = COPY $sgpr0 + %1:sgpr(s32) = COPY $sgpr1 + %2:scc(s1) = G_ICMP intpred(eq), %0, %1 + G_BRCOND %2, %bb.1 + G_BR %bb.1 + + bb.1: + + bb.2: + +... + +# Don't try to select this. +--- + +name: brcond_sgpr +legalized: true +regBankSelected: true + +body: | + ; GCN-LABEL: name: brcond_sgpr + ; GCN: bb.0: + ; GCN: successors: %bb.1(0x80000000) + ; GCN: [[COPY:%[0-9]+]]:sgpr(s32) = COPY $sgpr0 + ; GCN: [[TRUNC:%[0-9]+]]:sgpr(s1) = G_TRUNC [[COPY]](s32) + ; GCN: G_BRCOND [[TRUNC]](s1), %bb.1 + ; GCN: bb.1: + bb.0: + liveins: $sgpr0, $sgpr1 + + %0:sgpr(s32) = COPY $sgpr0 + %1:sgpr(s1) = G_TRUNC %0 + G_BRCOND %1, %bb.1 + + bb.1: + +... + + +# Don't try to select this for now. +--- + +name: brcond_vcc +legalized: true +regBankSelected: true + +body: | + ; GCN-LABEL: name: brcond_vcc + ; GCN: bb.0: + ; GCN: successors: %bb.1(0x80000000) + ; GCN: [[COPY:%[0-9]+]]:vgpr(s32) = COPY $vgpr0 + ; GCN: [[COPY1:%[0-9]+]]:vgpr(s32) = COPY $vgpr1 + ; GCN: [[ICMP:%[0-9]+]]:vcc(s1) = G_ICMP intpred(eq), [[COPY]](s32), [[COPY1]] + ; GCN: G_BRCOND [[ICMP]](s1), %bb.1 + ; GCN: bb.1: + bb.0: + liveins: $vgpr0, $vgpr1 + + %0:vgpr(s32) = COPY $vgpr0 + %1:vgpr(s32) = COPY $vgpr1 + %2:vcc(s1) = G_ICMP intpred(eq), %0, %1 + G_BRCOND %2, %bb.1 + + bb.1: + +... -- 2.50.1