[llvm] r269261 - All llvm.deoptimize declarations must use the same calling convention

Sanjoy Das via llvm-commits llvm-commits at lists.llvm.org
Wed May 11 18:17:38 PDT 2016


Author: sanjoy
Date: Wed May 11 20:17:38 2016
New Revision: 269261

URL: http://llvm.org/viewvc/llvm-project?rev=269261&view=rev
Log:
All llvm.deoptimize declarations must use the same calling convention

This new verifier rule lets us unambigously pick a calling convention
when creating a new declaration for
`@llvm.experimental.deoptimize.<ty>`.  It is also congruent with our
lowering strategy -- since all calls to `@llvm.experimental.deoptimize`
are lowered to calls to `__llvm_deoptimize`, it is reasonable to enforce
a unique calling convention.

Some of the tests that were breaking this verifier rule have had to be
split up into different .ll files.

The inliner was violating this rule as well, and has been fixed to avoid
producing invalid IR.

Added:
    llvm/trunk/test/CodeGen/X86/deopt-intrinsic-cconv.ll
    llvm/trunk/test/Transforms/Inline/deoptimize-intrinsic-cconv.ll
    llvm/trunk/test/Transforms/RewriteStatepointsForGC/deopt-intrinsic-cconv.ll
Modified:
    llvm/trunk/docs/LangRef.rst
    llvm/trunk/lib/IR/Verifier.cpp
    llvm/trunk/lib/Transforms/Utils/InlineFunction.cpp
    llvm/trunk/test/CodeGen/X86/deopt-intrinsic.ll
    llvm/trunk/test/Transforms/Inline/deoptimize-intrinsic.ll
    llvm/trunk/test/Transforms/RewriteStatepointsForGC/deopt-intrinsic.ll
    llvm/trunk/test/Verifier/deoptimize-intrinsic.ll

Modified: llvm/trunk/docs/LangRef.rst
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/docs/LangRef.rst?rev=269261&r1=269260&r2=269261&view=diff
==============================================================================
--- llvm/trunk/docs/LangRef.rst (original)
+++ llvm/trunk/docs/LangRef.rst Wed May 11 20:17:38 2016
@@ -12339,6 +12339,9 @@ The inliner composes the ``"deopt"`` con
 ``"deopt"`` continuations present in the inlinee, and also updates calls to this
 intrinsic to return directly from the frame of the function it inlined into.
 
+All declarations of ``@llvm.experimental.deoptimize`` must share the
+same calling convention.
+
 .. _deoptimize_lowering:
 
 Lowering:

Modified: llvm/trunk/lib/IR/Verifier.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/IR/Verifier.cpp?rev=269261&r1=269260&r2=269261&view=diff
==============================================================================
--- llvm/trunk/lib/IR/Verifier.cpp (original)
+++ llvm/trunk/lib/IR/Verifier.cpp Wed May 11 20:17:38 2016
@@ -243,6 +243,9 @@ class Verifier : public InstVisitor<Veri
   /// Cache of constants visited in search of ConstantExprs.
   SmallPtrSet<const Constant *, 32> ConstantExprVisited;
 
+  /// Cache of declarations of the llvm.experimental.deoptimize.<ty> intrinsic.
+  SmallVector<const Function *, 4> DeoptimizeDeclarations;
+
   // Verify that this GlobalValue is only used in this module.
   // This map is used to avoid visiting uses twice. We can arrive at a user
   // twice, if they have multiple operands. In particular for very large
@@ -322,8 +325,11 @@ public:
       visitGlobalValue(F);
 
       // Check to make sure function prototypes are okay.
-      if (F.isDeclaration())
+      if (F.isDeclaration()) {
         visitFunction(F);
+        if (F.getIntrinsicID() == Intrinsic::experimental_deoptimize)
+          DeoptimizeDeclarations.push_back(&F);
+      }
     }
 
     // Now that we've visited every function, verify that we never asked to
@@ -346,6 +352,8 @@ public:
 
     verifyCompileUnits();
 
+    verifyDeoptimizeCallingConvs();
+
     return !Broken;
   }
 
@@ -470,6 +478,10 @@ private:
 
   /// Module-level debug info verification...
   void verifyCompileUnits();
+
+  /// Module-level verification that all @llvm.experimental.deoptimize
+  /// declarations share the same calling convention.
+  void verifyDeoptimizeCallingConvs();
 };
 } // End anonymous namespace
 
@@ -4396,6 +4408,18 @@ void Verifier::verifyCompileUnits() {
   CUVisited.clear();
 }
 
+void Verifier::verifyDeoptimizeCallingConvs() {
+  if (DeoptimizeDeclarations.empty())
+    return;
+
+  const Function *First = DeoptimizeDeclarations[0];
+  for (auto *F : makeArrayRef(DeoptimizeDeclarations).slice(1))
+    Assert(First->getCallingConv() == F->getCallingConv(),
+           "All llvm.experimental.deoptimize declarations must have the same "
+           "calling convention",
+           First, F);
+}
+
 //===----------------------------------------------------------------------===//
 //  Implement the public interfaces to this file...
 //===----------------------------------------------------------------------===//

Modified: llvm/trunk/lib/Transforms/Utils/InlineFunction.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Utils/InlineFunction.cpp?rev=269261&r1=269260&r2=269261&view=diff
==============================================================================
--- llvm/trunk/lib/Transforms/Utils/InlineFunction.cpp (original)
+++ llvm/trunk/lib/Transforms/Utils/InlineFunction.cpp Wed May 11 20:17:38 2016
@@ -1874,7 +1874,13 @@ bool llvm::InlineFunction(CallSite CS, I
           continue;
         }
 
-        auto CallingConv = DeoptCall->getCallingConv();
+        // The calling convention on the deoptimize call itself may be bogus,
+        // since the code we're inlining may have undefined behavior (and may
+        // never actually execute at runtime); but all
+        // @llvm.experimental.deoptimize declarations have to have the same
+        // calling convention in a well-formed module.
+        auto CallingConv = DeoptCall->getCalledFunction()->getCallingConv();
+        NewDeoptIntrinsic->setCallingConv(CallingConv);
         auto *CurBB = RI->getParent();
         RI->eraseFromParent();
 

Added: llvm/trunk/test/CodeGen/X86/deopt-intrinsic-cconv.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/X86/deopt-intrinsic-cconv.ll?rev=269261&view=auto
==============================================================================
--- llvm/trunk/test/CodeGen/X86/deopt-intrinsic-cconv.ll (added)
+++ llvm/trunk/test/CodeGen/X86/deopt-intrinsic-cconv.ll Wed May 11 20:17:38 2016
@@ -0,0 +1,34 @@
+; RUN: llc < %s | FileCheck %s
+; RUN: llc -debug-only=stackmaps < %s 2>&1 | FileCheck --check-prefix=STACKMAPS %s
+; REQUIRES: asserts
+
+target datalayout = "e-m:o-i64:64-f80:128-n8:16:32:64-S128"
+target triple = "x86_64-apple-macosx10.11.0"
+
+declare webkit_jscc i64  @llvm.experimental.deoptimize.i64(...)
+
+define i64 @caller_1() {
+; CHECK-LABEL: _caller_1:
+; CHECK-NEXT: {{.+cfi.+}}
+; CHECK-NEXT: ##{{.+}}
+; CHECK-NEXT: pushq	%rax
+; CHECK-NEXT: {{Ltmp[0-9]+}}:
+; CHECK-NEXT: {{.+cfi.+}}
+; CHECK-NEXT: movl	$1140457472, (%rsp)     ## imm = 0x43FA0000
+; CHECK-NEXT: movl	$42, %eax
+; CHECK-NEXT: callq	___llvm_deoptimize
+; CHECK-NEXT: {{Ltmp[0-9]+}}:
+
+entry:
+  %v = call webkit_jscc i64(...) @llvm.experimental.deoptimize.i64(i32 42, float 500.0) [ "deopt"(i32 3) ]
+  ret i64 %v
+}
+
+; STACKMAPS: Stack Maps: callsites:
+; STACKMAPS-NEXT: Stack Maps: callsite 2882400015
+; STACKMAPS-NEXT: Stack Maps:   has 4 locations
+; STACKMAPS-NEXT: Stack Maps: 		Loc 0: Constant 12	[encoding: .byte 4, .byte 8, .short 0, .int 12]
+; STACKMAPS-NEXT: Stack Maps: 		Loc 1: Constant 0	[encoding: .byte 4, .byte 8, .short 0, .int 0]
+; STACKMAPS-NEXT: Stack Maps: 		Loc 2: Constant 1	[encoding: .byte 4, .byte 8, .short 0, .int 1]
+; STACKMAPS-NEXT: Stack Maps: 		Loc 3: Constant 3	[encoding: .byte 4, .byte 8, .short 0, .int 3]
+; STACKMAPS-NEXT: Stack Maps: 	has 0 live-out registers

Modified: llvm/trunk/test/CodeGen/X86/deopt-intrinsic.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/X86/deopt-intrinsic.ll?rev=269261&r1=269260&r2=269261&view=diff
==============================================================================
--- llvm/trunk/test/CodeGen/X86/deopt-intrinsic.ll (original)
+++ llvm/trunk/test/CodeGen/X86/deopt-intrinsic.ll Wed May 11 20:17:38 2016
@@ -7,7 +7,6 @@ target triple = "x86_64-apple-macosx10.1
 
 declare i32 @llvm.experimental.deoptimize.i32(...)
 declare i8  @llvm.experimental.deoptimize.i8(...)
-declare webkit_jscc i64  @llvm.experimental.deoptimize.i64(...)
 
 define i32 @caller_0() {
 ; CHECK-LABEL: _caller_0:
@@ -40,23 +39,6 @@ entry:
   ret i8 %v
 }
 
-define i64 @caller_2() {
-; CHECK-LABEL: _caller_2:
-; CHECK-NEXT: {{.+cfi.+}}
-; CHECK-NEXT: ##{{.+}}
-; CHECK-NEXT: pushq	%rax
-; CHECK-NEXT: {{Ltmp[0-9]+}}:
-; CHECK-NEXT: {{.+cfi.+}}
-; CHECK-NEXT: movl	$1140457472, (%rsp)     ## imm = 0x43FA0000
-; CHECK-NEXT: movl	$42, %eax
-; CHECK-NEXT: callq	___llvm_deoptimize
-; CHECK-NEXT: {{Ltmp[0-9]+}}:
-
-entry:
-  %v = call webkit_jscc i64(...) @llvm.experimental.deoptimize.i64(i32 42, float 500.0) [ "deopt"(i32 3) ]
-  ret i64 %v
-}
-
 ; STACKMAPS: Stack Maps: callsites:
 ; STACKMAPS-NEXT: Stack Maps: callsite 2882400015
 ; STACKMAPS-NEXT: Stack Maps:   has 4 locations
@@ -72,10 +54,3 @@ entry:
 ; STACKMAPS-NEXT: Stack Maps: 		Loc 2: Constant 1	[encoding: .byte 4, .byte 8, .short 0, .int 1]
 ; STACKMAPS-NEXT: Stack Maps: 		Loc 3: Constant 1	[encoding: .byte 4, .byte 8, .short 0, .int 1]
 ; STACKMAPS-NEXT: Stack Maps: 	has 0 live-out registers
-; STACKMAPS-NEXT: Stack Maps: callsite 2882400015
-; STACKMAPS-NEXT: Stack Maps:   has 4 locations
-; STACKMAPS-NEXT: Stack Maps: 		Loc 0: Constant 12	[encoding: .byte 4, .byte 8, .short 0, .int 12]
-; STACKMAPS-NEXT: Stack Maps: 		Loc 1: Constant 0	[encoding: .byte 4, .byte 8, .short 0, .int 0]
-; STACKMAPS-NEXT: Stack Maps: 		Loc 2: Constant 1	[encoding: .byte 4, .byte 8, .short 0, .int 1]
-; STACKMAPS-NEXT: Stack Maps: 		Loc 3: Constant 3	[encoding: .byte 4, .byte 8, .short 0, .int 3]
-; STACKMAPS-NEXT: Stack Maps: 	has 0 live-out registers

Added: llvm/trunk/test/Transforms/Inline/deoptimize-intrinsic-cconv.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Transforms/Inline/deoptimize-intrinsic-cconv.ll?rev=269261&view=auto
==============================================================================
--- llvm/trunk/test/Transforms/Inline/deoptimize-intrinsic-cconv.ll (added)
+++ llvm/trunk/test/Transforms/Inline/deoptimize-intrinsic-cconv.ll Wed May 11 20:17:38 2016
@@ -0,0 +1,19 @@
+; RUN: opt -S -always-inline < %s | FileCheck %s
+
+declare cc42 i32 @llvm.experimental.deoptimize.i32(...)
+
+define i32 @callee_with_coldcc() alwaysinline {
+  %v0 = call cc42 i32(...) @llvm.experimental.deoptimize.i32(i32 1) [ "deopt"() ]
+  ret i32 %v0
+}
+
+define void @caller_with_coldcc() {
+; CHECK-LABEL: @caller_with_coldcc(
+; CHECK-NEXT:  call cc42 void (...) @llvm.experimental.deoptimize.isVoid(i32 1) [ "deopt"() ]
+; CHECK-NEXT:  ret void
+
+  %val = call i32 @callee_with_coldcc()
+  ret void
+}
+
+; CHECK: declare cc42 void @llvm.experimental.deoptimize.isVoid(...)

Modified: llvm/trunk/test/Transforms/Inline/deoptimize-intrinsic.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Transforms/Inline/deoptimize-intrinsic.ll?rev=269261&r1=269260&r2=269261&view=diff
==============================================================================
--- llvm/trunk/test/Transforms/Inline/deoptimize-intrinsic.ll (original)
+++ llvm/trunk/test/Transforms/Inline/deoptimize-intrinsic.ll Wed May 11 20:17:38 2016
@@ -1,7 +1,7 @@
 ; RUN: opt -S -always-inline < %s | FileCheck %s
 
 declare i8 @llvm.experimental.deoptimize.i8(...)
-declare cc42 i32 @llvm.experimental.deoptimize.i32(...)
+declare i32 @llvm.experimental.deoptimize.i32(...)
 
 define i8 @callee(i1* %c) alwaysinline {
   %c0 = load volatile i1, i1* %c
@@ -121,17 +121,3 @@ define void @caller_with_stacksaverestor
   call i8 @callee_with_dynamic_alloca(i32 %n)
   ret void
 }
-
-define i32 @callee_with_coldcc() alwaysinline {
-  %v0 = call cc42 i32(...) @llvm.experimental.deoptimize.i32(i32 1) [ "deopt"() ]
-  ret i32 %v0
-}
-
-define void @caller_with_coldcc() {
-; CHECK-LABEL: @caller_with_coldcc(
-; CHECK-NEXT:  call cc42 void (...) @llvm.experimental.deoptimize.isVoid(i32 1) [ "deopt"() ]
-; CHECK-NEXT:  ret void
-
-  %val = call i32 @callee_with_coldcc()
-  ret void
-}

Added: llvm/trunk/test/Transforms/RewriteStatepointsForGC/deopt-intrinsic-cconv.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Transforms/RewriteStatepointsForGC/deopt-intrinsic-cconv.ll?rev=269261&view=auto
==============================================================================
--- llvm/trunk/test/Transforms/RewriteStatepointsForGC/deopt-intrinsic-cconv.ll (added)
+++ llvm/trunk/test/Transforms/RewriteStatepointsForGC/deopt-intrinsic-cconv.ll Wed May 11 20:17:38 2016
@@ -0,0 +1,16 @@
+; RUN: opt -rewrite-statepoints-for-gc -S < %s | FileCheck %s
+
+target datalayout = "e-m:o-i64:64-f80:128-n8:16:32:64-S128"
+target triple = "x86_64-apple-macosx10.11.0"
+
+declare cc42 double @llvm.experimental.deoptimize.f64(...)
+
+define double @caller_3() gc "statepoint-example" {
+; CHECK-LABELL @caller_3(
+; CHECK: call cc42 token (i64, i32, void ()*, i32, i32, ...) @llvm.experimental.gc.statepoint
+; CHECK:  unreachable
+
+entry:
+  %val = call cc42 double(...) @llvm.experimental.deoptimize.f64() [ "deopt"() ]
+  ret double %val
+}

Modified: llvm/trunk/test/Transforms/RewriteStatepointsForGC/deopt-intrinsic.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Transforms/RewriteStatepointsForGC/deopt-intrinsic.ll?rev=269261&r1=269260&r2=269261&view=diff
==============================================================================
--- llvm/trunk/test/Transforms/RewriteStatepointsForGC/deopt-intrinsic.ll (original)
+++ llvm/trunk/test/Transforms/RewriteStatepointsForGC/deopt-intrinsic.ll Wed May 11 20:17:38 2016
@@ -5,7 +5,6 @@ target triple = "x86_64-apple-macosx10.1
 
 declare i32 @llvm.experimental.deoptimize.i32(...)
 declare void @llvm.experimental.deoptimize.isVoid(...)
-declare cc42 double @llvm.experimental.deoptimize.f64(...)
 
 define i32 @caller_0(i32 addrspace(1)* %ptr) gc "statepoint-example" {
 ; CHECK-LABEL: @caller_0(
@@ -34,13 +33,3 @@ entry:
   call void(...) @llvm.experimental.deoptimize.isVoid() [ "deopt"(i32 0, i32 addrspace(1)* %ptr) ]
   ret void
 }
-
-define double @caller_3() gc "statepoint-example" {
-; CHECK-LABELL @caller_3(
-; CHECK: call cc42 token (i64, i32, void ()*, i32, i32, ...) @llvm.experimental.gc.statepoint
-; CHECK:  unreachable
-
-entry:
-  %val = call cc42 double(...) @llvm.experimental.deoptimize.f64() [ "deopt"() ]
-  ret double %val
-}

Modified: llvm/trunk/test/Verifier/deoptimize-intrinsic.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Verifier/deoptimize-intrinsic.ll?rev=269261&r1=269260&r2=269261&view=diff
==============================================================================
--- llvm/trunk/test/Verifier/deoptimize-intrinsic.ll (original)
+++ llvm/trunk/test/Verifier/deoptimize-intrinsic.ll Wed May 11 20:17:38 2016
@@ -2,6 +2,7 @@
 
 declare i8 @llvm.experimental.deoptimize.i8(...)
 declare void @llvm.experimental.deoptimize.isVoid(...)
+declare cc40 void @llvm.experimental.deoptimize.double(...)
 
 declare void @unknown()
 
@@ -40,3 +41,5 @@ entry:
 ; CHECK: calls to experimental_deoptimize must be followed by a return of the value computed by experimental_deoptimize
   ret i8 0
 }
+
+; CHECK: All llvm.experimental.deoptimize declarations must have the same calling convention




More information about the llvm-commits mailing list