[llvm] 4d188a6 - [Verifier] Require same signature for intrinsic calls

Nikita Popov via llvm-commits llvm-commits at lists.llvm.org
Fri Jul 16 09:33:34 PDT 2021


Author: Nikita Popov
Date: 2021-07-16T18:33:16+02:00
New Revision: 4d188a6524083ef79dae910215d4b34fad595358

URL: https://github.com/llvm/llvm-project/commit/4d188a6524083ef79dae910215d4b34fad595358
DIFF: https://github.com/llvm/llvm-project/commit/4d188a6524083ef79dae910215d4b34fad595358.diff

LOG: [Verifier] Require same signature for intrinsic calls

As suggested on D105733, this adds a verifier rule that calls to
intrinsics must match the signature of the intrinsic.

Without opaque pointers this is automatically enforced for all
calls, because the pointer types need to match. If the signatures
don't match, a pointer bitcast has to be inserted. For intrinsics
in particular, such bitcasts are not legal, because the address of
intrinsics cannot be taken.

With opaque pointers, there are no more pointer bitcasts, so it's
generally possible for the call and the callee signature to differ.
However, for intrinsics we still want to enforce that the signatures
must match, the same as was done before through the address taken
check.

We can't enforce this more generally for non-intrinsics, because
calls with mismatched signatures at the very least can legally
occur in unreachable code, and might also be valid in some other
cases, depending on how exactly the signatures differ.

Differential Revision: https://reviews.llvm.org/D106013

Added: 
    llvm/test/Verifier/force-opaque-ptr.ll

Modified: 
    llvm/lib/IR/Verifier.cpp

Removed: 
    


################################################################################
diff  --git a/llvm/lib/IR/Verifier.cpp b/llvm/lib/IR/Verifier.cpp
index 67ed73ff8f0e9..d23603c776b81 100644
--- a/llvm/lib/IR/Verifier.cpp
+++ b/llvm/lib/IR/Verifier.cpp
@@ -3064,11 +3064,12 @@ void Verifier::visitCallBase(CallBase &Call) {
   Assert(verifyAttributeCount(Attrs, Call.arg_size()),
          "Attribute after last parameter!", Call);
 
-  bool IsIntrinsic = Call.getCalledFunction() &&
-                     Call.getCalledFunction()->isIntrinsic();
-
   Function *Callee =
       dyn_cast<Function>(Call.getCalledOperand()->stripPointerCasts());
+  bool IsIntrinsic = Callee && Callee->isIntrinsic();
+  if (IsIntrinsic)
+    Assert(Callee->getValueType() == FTy,
+           "Intrinsic called with incompatible signature", Call);
 
   if (Attrs.hasFnAttribute(Attribute::Speculatable)) {
     // Don't allow speculatable on call sites, unless the underlying function

diff  --git a/llvm/test/Verifier/force-opaque-ptr.ll b/llvm/test/Verifier/force-opaque-ptr.ll
new file mode 100644
index 0000000000000..913480bd32453
--- /dev/null
+++ b/llvm/test/Verifier/force-opaque-ptr.ll
@@ -0,0 +1,9 @@
+; RUN: not opt -passes=verify -force-opaque-pointers -S < %s 2>&1 | FileCheck %s
+
+declare i32 @llvm.umax.i32(i32, i32)
+
+define void @intrinsic_signature_mismatch() {
+; CHECK: Intrinsic called with incompatible signature
+  call i32 @llvm.umax.i32(i32 0)
+  ret void
+}


        


More information about the llvm-commits mailing list