summaryrefslogtreecommitdiffstats
path: root/llvm/lib
diff options
context:
space:
mode:
Diffstat (limited to 'llvm/lib')
-rw-r--r--llvm/lib/Target/AMDGPU/SIAnnotateControlFlow.cpp3
-rw-r--r--llvm/lib/Target/AMDGPU/SIISelLowering.cpp64
-rw-r--r--llvm/lib/Target/AMDGPU/SIInstrFormats.td3
-rw-r--r--llvm/lib/Target/AMDGPU/SIInstructions.td23
-rw-r--r--llvm/lib/Target/AMDGPU/SIIntrinsics.td14
5 files changed, 80 insertions, 27 deletions
diff --git a/llvm/lib/Target/AMDGPU/SIAnnotateControlFlow.cpp b/llvm/lib/Target/AMDGPU/SIAnnotateControlFlow.cpp
index 032f4c1f7b6..5e73a7d90cd 100644
--- a/llvm/lib/Target/AMDGPU/SIAnnotateControlFlow.cpp
+++ b/llvm/lib/Target/AMDGPU/SIAnnotateControlFlow.cpp
@@ -148,12 +148,15 @@ bool SIAnnotateControlFlow::doInitialization(Module &M) {
Break = M.getOrInsertFunction(
BreakIntrinsic, Int64, Int64, (Type *)nullptr);
+ cast<Function>(Break)->setDoesNotAccessMemory();
IfBreak = M.getOrInsertFunction(
IfBreakIntrinsic, Int64, Boolean, Int64, (Type *)nullptr);
+ cast<Function>(IfBreak)->setDoesNotAccessMemory();;
ElseBreak = M.getOrInsertFunction(
ElseBreakIntrinsic, Int64, Int64, Int64, (Type *)nullptr);
+ cast<Function>(ElseBreak)->setDoesNotAccessMemory();
Loop = M.getOrInsertFunction(
LoopIntrinsic, Boolean, Int64, (Type *)nullptr);
diff --git a/llvm/lib/Target/AMDGPU/SIISelLowering.cpp b/llvm/lib/Target/AMDGPU/SIISelLowering.cpp
index 92c832f7a46..4570fe585d1 100644
--- a/llvm/lib/Target/AMDGPU/SIISelLowering.cpp
+++ b/llvm/lib/Target/AMDGPU/SIISelLowering.cpp
@@ -1643,20 +1643,30 @@ SDValue SITargetLowering::LowerFrameIndex(SDValue Op, SelectionDAG &DAG) const {
}
bool SITargetLowering::isCFIntrinsic(const SDNode *Intr) const {
- if (Intr->getOpcode() != ISD::INTRINSIC_W_CHAIN)
- return false;
+ if (Intr->getOpcode() == ISD::INTRINSIC_W_CHAIN) {
+ switch (cast<ConstantSDNode>(Intr->getOperand(1))->getZExtValue()) {
+ case AMDGPUIntrinsic::amdgcn_if:
+ case AMDGPUIntrinsic::amdgcn_else:
+ case AMDGPUIntrinsic::amdgcn_end_cf:
+ case AMDGPUIntrinsic::amdgcn_loop:
+ return true;
+ default:
+ return false;
+ }
+ }
- switch (cast<ConstantSDNode>(Intr->getOperand(1))->getZExtValue()) {
- default: return false;
- case AMDGPUIntrinsic::amdgcn_if:
- case AMDGPUIntrinsic::amdgcn_else:
- case AMDGPUIntrinsic::amdgcn_break:
- case AMDGPUIntrinsic::amdgcn_if_break:
- case AMDGPUIntrinsic::amdgcn_else_break:
- case AMDGPUIntrinsic::amdgcn_loop:
- case AMDGPUIntrinsic::amdgcn_end_cf:
- return true;
+ if (Intr->getOpcode() == ISD::INTRINSIC_WO_CHAIN) {
+ switch (cast<ConstantSDNode>(Intr->getOperand(0))->getZExtValue()) {
+ case AMDGPUIntrinsic::amdgcn_break:
+ case AMDGPUIntrinsic::amdgcn_if_break:
+ case AMDGPUIntrinsic::amdgcn_else_break:
+ return true;
+ default:
+ return false;
+ }
}
+
+ return false;
}
void SITargetLowering::createDebuggerPrologueStackObjects(
@@ -1708,30 +1718,50 @@ SDValue SITargetLowering::LowerBRCOND(SDValue BRCOND,
Target = BR->getOperand(1);
}
+ // FIXME: This changes the types of the intrinsics instead of introducing new
+ // nodes with the correct types.
+ // e.g. llvm.amdgcn.loop
+
+ // eg: i1,ch = llvm.amdgcn.loop t0, TargetConstant:i32<6271>, t3
+ // => t9: ch = llvm.amdgcn.loop t0, TargetConstant:i32<6271>, t3, BasicBlock:ch<bb1 0x7fee5286d088>
+
if (!isCFIntrinsic(Intr)) {
// This is a uniform branch so we don't need to legalize.
return BRCOND;
}
+ bool HaveChain = Intr->getOpcode() == ISD::INTRINSIC_VOID ||
+ Intr->getOpcode() == ISD::INTRINSIC_W_CHAIN;
+
assert(!SetCC ||
(SetCC->getConstantOperandVal(1) == 1 &&
cast<CondCodeSDNode>(SetCC->getOperand(2).getNode())->get() ==
ISD::SETNE));
- // Build the result and
- ArrayRef<EVT> Res(Intr->value_begin() + 1, Intr->value_end());
-
// operands of the new intrinsic call
SmallVector<SDValue, 4> Ops;
- Ops.push_back(BRCOND.getOperand(0));
- Ops.append(Intr->op_begin() + 1, Intr->op_end());
+ if (HaveChain)
+ Ops.push_back(BRCOND.getOperand(0));
+
+ Ops.append(Intr->op_begin() + (HaveChain ? 1 : 0), Intr->op_end());
Ops.push_back(Target);
+ ArrayRef<EVT> Res(Intr->value_begin() + 1, Intr->value_end());
+
// build the new intrinsic call
SDNode *Result = DAG.getNode(
Res.size() > 1 ? ISD::INTRINSIC_W_CHAIN : ISD::INTRINSIC_VOID, DL,
DAG.getVTList(Res), Ops).getNode();
+ if (!HaveChain) {
+ SDValue Ops[] = {
+ SDValue(Result, 0),
+ BRCOND.getOperand(0)
+ };
+
+ Result = DAG.getMergeValues(Ops, DL).getNode();
+ }
+
if (BR) {
// Give the branch instruction our target
SDValue Ops[] = {
diff --git a/llvm/lib/Target/AMDGPU/SIInstrFormats.td b/llvm/lib/Target/AMDGPU/SIInstrFormats.td
index 33b9b122e2e..4957b660616 100644
--- a/llvm/lib/Target/AMDGPU/SIInstrFormats.td
+++ b/llvm/lib/Target/AMDGPU/SIInstrFormats.td
@@ -128,6 +128,9 @@ class CFPseudoInstSI<dag outs, dag ins, list<dag> pattern = [],
let Uses = !if(UseExec, [EXEC], []);
let Defs = !if(DefExec, [EXEC, SCC], [SCC]);
+ let mayLoad = 0;
+ let mayStore = 0;
+ let hasSideEffects = 0;
}
class Enc32 {
diff --git a/llvm/lib/Target/AMDGPU/SIInstructions.td b/llvm/lib/Target/AMDGPU/SIInstructions.td
index 38b0f15dd36..e201736cc2f 100644
--- a/llvm/lib/Target/AMDGPU/SIInstructions.td
+++ b/llvm/lib/Target/AMDGPU/SIInstructions.td
@@ -1024,8 +1024,6 @@ def GET_GROUPSTATICSIZE : PseudoInstSI <(outs SReg_32:$sdst), (ins),
// SI pseudo instructions. These are used by the CFG structurizer pass
// and should be lowered to ISA instructions prior to codegen.
-let hasSideEffects = 1 in {
-
// Dummy terminator instruction to use after control flow instructions
// replaced with exec mask operations.
def SI_MASK_BRANCH : PseudoInstSI <
@@ -1044,12 +1042,18 @@ def SI_IF: CFPseudoInstSI <
[(set i64:$dst, (int_amdgcn_if i1:$vcc, bb:$target))], 1, 1> {
let Constraints = "";
let Size = 8;
+ let mayStore = 1;
+ let mayLoad = 1;
+ let hasSideEffects = 1;
}
def SI_ELSE : CFPseudoInstSI <
(outs SReg_64:$dst), (ins SReg_64:$src, brtarget:$target, i1imm:$execfix), [], 1, 1> {
let Constraints = "$src = $dst";
let Size = 12;
+ let mayStore = 1;
+ let mayLoad = 1;
+ let hasSideEffects = 1;
}
def SI_LOOP : CFPseudoInstSI <
@@ -1057,6 +1061,9 @@ def SI_LOOP : CFPseudoInstSI <
[(int_amdgcn_loop i64:$saved, bb:$target)], 1, 1> {
let Size = 8;
let isBranch = 1;
+ let hasSideEffects = 1;
+ let mayLoad = 1;
+ let mayStore = 1;
}
} // End isBranch = 1, isTerminator = 1
@@ -1065,24 +1072,35 @@ def SI_END_CF : CFPseudoInstSI <
(outs), (ins SReg_64:$saved),
[(int_amdgcn_end_cf i64:$saved)], 1, 1> {
let Size = 4;
+ let isAsCheapAsAMove = 1;
+ let isReMaterializable = 1;
+ let mayLoad = 1;
+ let mayStore = 1;
+ let hasSideEffects = 1;
}
def SI_BREAK : CFPseudoInstSI <
(outs SReg_64:$dst), (ins SReg_64:$src),
[(set i64:$dst, (int_amdgcn_break i64:$src))], 1> {
let Size = 4;
+ let isAsCheapAsAMove = 1;
+ let isReMaterializable = 1;
}
def SI_IF_BREAK : CFPseudoInstSI <
(outs SReg_64:$dst), (ins SReg_64:$vcc, SReg_64:$src),
[(set i64:$dst, (int_amdgcn_if_break i1:$vcc, i64:$src))]> {
let Size = 4;
+ let isAsCheapAsAMove = 1;
+ let isReMaterializable = 1;
}
def SI_ELSE_BREAK : CFPseudoInstSI <
(outs SReg_64:$dst), (ins SReg_64:$src0, SReg_64:$src1),
[(set i64:$dst, (int_amdgcn_else_break i64:$src0, i64:$src1))]> {
let Size = 4;
+ let isAsCheapAsAMove = 1;
+ let isReMaterializable = 1;
}
let Uses = [EXEC], Defs = [EXEC,VCC] in {
@@ -1100,7 +1118,6 @@ def SI_KILL_TERMINATOR : SPseudoInstSI <
} // End Uses = [EXEC], Defs = [EXEC,VCC]
-} // End mayLoad = 1, mayStore = 1, hasSideEffects = 1
def SI_PS_LIVE : PseudoInstSI <
(outs SReg_64:$dst), (ins),
diff --git a/llvm/lib/Target/AMDGPU/SIIntrinsics.td b/llvm/lib/Target/AMDGPU/SIIntrinsics.td
index 9d06ccfc6c7..b2857f06cbb 100644
--- a/llvm/lib/Target/AMDGPU/SIIntrinsics.td
+++ b/llvm/lib/Target/AMDGPU/SIIntrinsics.td
@@ -186,11 +186,11 @@ let TargetPrefix = "amdgcn", isTarget = 1 in {
/* Control flow Intrinsics */
- def int_amdgcn_if : Intrinsic<[llvm_i64_ty], [llvm_i1_ty, llvm_empty_ty], []>;
- def int_amdgcn_else : Intrinsic<[llvm_i64_ty], [llvm_i64_ty, llvm_empty_ty], []>;
- def int_amdgcn_break : Intrinsic<[llvm_i64_ty], [llvm_i64_ty], []>;
- def int_amdgcn_if_break : Intrinsic<[llvm_i64_ty], [llvm_i1_ty, llvm_i64_ty], []>;
- def int_amdgcn_else_break : Intrinsic<[llvm_i64_ty], [llvm_i64_ty, llvm_i64_ty], []>;
- def int_amdgcn_loop : Intrinsic<[], [llvm_i64_ty, llvm_empty_ty], []>;
- def int_amdgcn_end_cf : Intrinsic<[], [llvm_i64_ty], []>;
+ def int_amdgcn_if : Intrinsic<[llvm_i64_ty], [llvm_i1_ty, llvm_empty_ty], [IntrConvergent]>;
+ def int_amdgcn_else : Intrinsic<[llvm_i64_ty], [llvm_i64_ty, llvm_empty_ty], [IntrConvergent]>;
+ def int_amdgcn_break : Intrinsic<[llvm_i64_ty], [llvm_i64_ty], [IntrNoMem, IntrConvergent]>;
+ def int_amdgcn_if_break : Intrinsic<[llvm_i64_ty], [llvm_i1_ty, llvm_i64_ty], [IntrNoMem, IntrConvergent]>;
+ def int_amdgcn_else_break : Intrinsic<[llvm_i64_ty], [llvm_i64_ty, llvm_i64_ty], [IntrNoMem, IntrConvergent]>;
+ def int_amdgcn_loop : Intrinsic<[], [llvm_i64_ty, llvm_empty_ty], [IntrConvergent]>;
+ def int_amdgcn_end_cf : Intrinsic<[], [llvm_i64_ty], [IntrConvergent]>;
}
OpenPOWER on IntegriCloud