]> granicus.if.org Git - llvm/commitdiff
AMDGPU: Add convergent flag to INLINEASM instruction.
authorWei Ding <wei.ding2@amd.com>
Wed, 22 Jun 2016 18:51:08 +0000 (18:51 +0000)
committerWei Ding <wei.ding2@amd.com>
Wed, 22 Jun 2016 18:51:08 +0000 (18:51 +0000)
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
include/llvm/IR/InlineAsm.h
lib/CodeGen/MachineInstr.cpp
lib/CodeGen/MachineVerifier.cpp
lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp
test/CodeGen/AMDGPU/convergent-inlineasm.ll [new file with mode: 0644]

index ea4e483a94bb87193f62a57c041a469112c91e42..8f1cb9b6f6590a993868b142e88db886fff0ca3a 100644 (file)
@@ -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);
   }
 
index d2e9e48539ceb430d393fb50946299f4ef994f06..d8f515e570adec2c052d8e1440ebd2f349ca05a0 100644 (file)
@@ -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
index 4789538e05b40dbd60415f952fbb88da671f636e..0b55d2e0b4319c8b317b669cd9b51beb92484d39 100644 (file)
@@ -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)
index 8b83e10ee7633bc60ff9e4b331f34c053ede7728..f5c349b59edc1c3570bea586fea0acca45d766a0 100644 (file)
@@ -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");
index 028e07f2b6a9f84f186ed9dd6173616fad716639..de20a60d879b65b5cca3e182f98206789744c246 100644 (file)
@@ -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 (file)
index 0000000..55a38e5
--- /dev/null
@@ -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 }