[PATCH] Make variable argument intrinsics behave correctly in a Win64 CC function.

Charles Davis cdavis5x at gmail.com
Fri Sep 13 11:38:39 PDT 2013



================
Comment at: lib/Transforms/Instrumentation/MemorySanitizer.cpp:1941
@@ +1940,3 @@
+      if (Cast->getSrcTy() ==
+            Type::getInt8PtrTy(Cast->getContext())->getPointerTo())
+        return;
----------------
Evgeniy Stepanov wrote:
> Evgeniy Stepanov wrote:
> > This looks very fragile.
> > Why can't you decide this based on the calling convention of the instrumented function?
> OK, va_list may be from a function with a different calling convention.
> I don't see a better way to detect this, but... how does va_copy work in this case? It gets plain i8* as an argument.
Remember how LLVM IR works--it's single-static assignment. All instructions are values. The IR for a Win64 ABI `va_copy` typically looks something like this:

  lang=llvm
  %ap = alloca i8*, align 8
  %cp = alloca i8*, align 8
  %ap1 = bitcast i8** %ap to i8*
  %cp1 = bitcast i8** %cp to i8*
  call void @llvm.va_copy(i8* %cp1, i8* %ap1)

So, I `dyn_cast` the argument to an `llvm::BitCastInst` (and hope that the optimizer didn't make the bitcast go away--yes, this is very fragile, but I can't think of any better way to do this), and check if the source type is a `i8**` (the argument to the `bitcast` is a pointer to the `va_list` itself). If it is, we assume it's a Win64 ABI `va_copy`, else, a System V ABI `va_copy`.

Now that I think about it, it might be better if I just add a new intrinsic (`llvm.ms_va_copy`, maybe?) to handle Win64 ABI `va_copy` calls, but when I tried to do it this way, I couldn't work out how to use the generic lowering code (that I pulled out of `LegalizeDAG`) to lower it. (In retrospect, I should probably have asked about it earlier on the list.)


http://llvm-reviews.chandlerc.com/D1622

BRANCH
  x64-ms-va_list

ARCANIST PROJECT
  llvm



More information about the llvm-commits mailing list