From ef8696380610895af98c494fd77d1f9a7ae8b35d Mon Sep 17 00:00:00 2001 From: Wei Ding Date: Wed, 22 Jun 2016 18:51:08 +0000 Subject: [PATCH] AMDGPU: Add convergent flag to INLINEASM instruction. Differential Revision: http://reviews.llvm.org/D21214 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@273455 91177308-0d34-0410-b5e6-96231b3b80d8 --- include/llvm/CodeGen/MachineInstr.h | 5 +++ include/llvm/IR/InlineAsm.h | 1 + lib/CodeGen/MachineInstr.cpp | 2 + lib/CodeGen/MachineVerifier.cpp | 5 ++- .../SelectionDAG/SelectionDAGBuilder.cpp | 2 + test/CodeGen/AMDGPU/convergent-inlineasm.ll | 45 +++++++++++++++++++ 6 files changed, 58 insertions(+), 2 deletions(-) create mode 100644 test/CodeGen/AMDGPU/convergent-inlineasm.ll diff --git a/include/llvm/CodeGen/MachineInstr.h b/include/llvm/CodeGen/MachineInstr.h index ea4e483a94b..8f1cb9b6f65 100644 --- a/include/llvm/CodeGen/MachineInstr.h +++ b/include/llvm/CodeGen/MachineInstr.h @@ -526,6 +526,11 @@ public: /// Convergent instructions can not be made control-dependent on any /// additional values. bool isConvergent(QueryType Type = AnyInBundle) const { + if (isInlineAsm()) { + unsigned ExtraInfo = getOperand(InlineAsm::MIOp_ExtraInfo).getImm(); + if (ExtraInfo & InlineAsm::Extra_IsConvergent) + return true; + } return hasProperty(MCID::Convergent, Type); } diff --git a/include/llvm/IR/InlineAsm.h b/include/llvm/IR/InlineAsm.h index d2e9e48539c..d8f515e570a 100644 --- a/include/llvm/IR/InlineAsm.h +++ b/include/llvm/IR/InlineAsm.h @@ -223,6 +223,7 @@ public: Extra_AsmDialect = 4, Extra_MayLoad = 8, Extra_MayStore = 16, + Extra_IsConvergent = 32, // Inline asm operands map to multiple SDNode / MachineInstr operands. // The first operand is an immediate describing the asm operand, the low diff --git a/lib/CodeGen/MachineInstr.cpp b/lib/CodeGen/MachineInstr.cpp index 4789538e05b..0b55d2e0b43 100644 --- a/lib/CodeGen/MachineInstr.cpp +++ b/lib/CodeGen/MachineInstr.cpp @@ -1754,6 +1754,8 @@ void MachineInstr::print(raw_ostream &OS, ModuleSlotTracker &MST, OS << " [mayload]"; if (ExtraInfo & InlineAsm::Extra_MayStore) OS << " [maystore]"; + if (ExtraInfo & InlineAsm::Extra_IsConvergent) + OS << " [isconvergent]"; if (ExtraInfo & InlineAsm::Extra_IsAlignStack) OS << " [alignstack]"; if (getInlineAsmDialect() == InlineAsm::AD_ATT) diff --git a/lib/CodeGen/MachineVerifier.cpp b/lib/CodeGen/MachineVerifier.cpp index 8b83e10ee76..f5c349b59ed 100644 --- a/lib/CodeGen/MachineVerifier.cpp +++ b/lib/CodeGen/MachineVerifier.cpp @@ -810,8 +810,9 @@ void MachineVerifier::verifyInlineAsm(const MachineInstr *MI) { if (!MI->getOperand(1).isImm()) report("Asm flags must be an immediate", MI); // Allowed flags are Extra_HasSideEffects = 1, Extra_IsAlignStack = 2, - // Extra_AsmDialect = 4, Extra_MayLoad = 8, and Extra_MayStore = 16. - if (!isUInt<5>(MI->getOperand(1).getImm())) + // Extra_AsmDialect = 4, Extra_MayLoad = 8, and Extra_MayStore = 16, + // and Extra_IsConvergent = 32. + if (!isUInt<6>(MI->getOperand(1).getImm())) report("Unknown asm flags", &MI->getOperand(1), 1); static_assert(InlineAsm::MIOp_FirstOperand == 2, "Asm format changed"); diff --git a/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp b/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp index 028e07f2b6a..de20a60d879 100644 --- a/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp +++ b/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp @@ -6763,6 +6763,8 @@ void SelectionDAGBuilder::visitInlineAsm(ImmutableCallSite CS) { ExtraInfo |= InlineAsm::Extra_HasSideEffects; if (IA->isAlignStack()) ExtraInfo |= InlineAsm::Extra_IsAlignStack; + if (CS.isConvergent()) + ExtraInfo |= InlineAsm::Extra_IsConvergent; // Set the asm dialect. ExtraInfo |= IA->getDialect() * InlineAsm::Extra_AsmDialect; diff --git a/test/CodeGen/AMDGPU/convergent-inlineasm.ll b/test/CodeGen/AMDGPU/convergent-inlineasm.ll new file mode 100644 index 00000000000..55a38e576ad --- /dev/null +++ b/test/CodeGen/AMDGPU/convergent-inlineasm.ll @@ -0,0 +1,45 @@ +; RUN: llc -mtriple=amdgcn--amdhsa -verify-machineinstrs < %s | FileCheck -check-prefix=GCN %s + +declare i32 @llvm.amdgcn.workitem.id.x() #0 +; GCN-LABEL: {{^}}convergent_inlineasm: +; GCN: BB#0: +; GCN: v_cmp_ne_i32_e64 +; GCN: BB#1: +define void @convergent_inlineasm(i64 addrspace(1)* nocapture %arg) { +bb: + %tmp = call i32 @llvm.amdgcn.workitem.id.x() + %tmp1 = tail call i64 asm "v_cmp_ne_i32_e64 $0, 0, $1", "=s,v"(i32 1) #1 + %tmp2 = icmp eq i32 %tmp, 8 + br i1 %tmp2, label %bb3, label %bb5 + +bb3: ; preds = %bb + %tmp4 = getelementptr i64, i64 addrspace(1)* %arg, i32 %tmp + store i64 %tmp1, i64 addrspace(1)* %arg, align 8 + br label %bb5 + +bb5: ; preds = %bb3, %bb + ret void +} + +; GCN-LABEL: {{^}}nonconvergent_inlineasm: +; GCN: BB#1: +; GCN: v_cmp_ne_i32_e64 +; GCN: BB1_2: +define void @nonconvergent_inlineasm(i64 addrspace(1)* nocapture %arg) { +bb: + %tmp = call i32 @llvm.amdgcn.workitem.id.x() + %tmp1 = tail call i64 asm "v_cmp_ne_i32_e64 $0, 0, $1", "=s,v"(i32 1) + %tmp2 = icmp eq i32 %tmp, 8 + br i1 %tmp2, label %bb3, label %bb5 + +bb3: ; preds = %bb + %tmp4 = getelementptr i64, i64 addrspace(1)* %arg, i32 %tmp + store i64 %tmp1, i64 addrspace(1)* %arg, align 8 + br label %bb5 + +bb5: ; preds = %bb3, %bb + ret void +} + +attributes #0 = { nounwind readnone } +attributes #1 = { convergent nounwind readnone } -- 2.50.1