Skip to content
This repository was archived by the owner on Nov 1, 2021. It is now read-only.

Commit ffdd8da

Browse files
committed
Emscripten: do not simplify varargs calls to jsargs, exception and resume intrinsics
See: 7216560 daf116d 59962e9 R=dschuff@chromium.org, azakai@mozilla.com BUG= https://code.google.com/p/nativeclient/issues/detail?id=4102 TEST= make check Review URL: https://codereview.chromium.org/1042043002
1 parent bf706a5 commit ffdd8da

File tree

2 files changed

+55
-9
lines changed

2 files changed

+55
-9
lines changed

lib/Transforms/NaCl/ExpandVarArgs.cpp

+27-9
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717
//===----------------------------------------------------------------------===//
1818

1919
#include "llvm/ADT/SmallVector.h"
20+
#include "llvm/ADT/Triple.h"
2021
#include "llvm/IR/Constants.h"
2122
#include "llvm/IR/DataLayout.h"
2223
#include "llvm/IR/Function.h"
@@ -45,7 +46,22 @@ INITIALIZE_PASS(ExpandVarArgs, "expand-varargs",
4546
"Expand out variable argument function definitions and calls",
4647
false, false)
4748

48-
static void ExpandVarArgFunc(Function *Func) {
49+
static bool isEmscriptenJSArgsFunc(Module *M, StringRef Name) {
50+
// TODO(jfb) Make these intrinsics in clang and remove the assert: these
51+
// intrinsics should only exist for Emscripten.
52+
bool isEmscriptenSpecial = Name.equals("emscripten_asm_const_int") ||
53+
Name.equals("emscripten_asm_const_double") ||
54+
Name.equals("emscripten_landingpad") ||
55+
Name.equals("emscripten_resume");
56+
assert(isEmscriptenSpecial ? Triple(M->getTargetTriple()).isOSEmscripten()
57+
: true);
58+
return isEmscriptenSpecial;
59+
}
60+
61+
static bool ExpandVarArgFunc(Module *M, Function *Func) {
62+
if (isEmscriptenJSArgsFunc(M, Func->getName()))
63+
return false;
64+
4965
Type *PtrType = Type::getInt8PtrTy(Func->getContext());
5066

5167
FunctionType *FTy = Func->getFunctionType();
@@ -84,6 +100,8 @@ static void ExpandVarArgFunc(Function *Func) {
84100
}
85101
}
86102
}
103+
104+
return true;
87105
}
88106

89107
static void ExpandVAArgInst(VAArgInst *Inst, DataLayout *DL) {
@@ -146,14 +164,16 @@ static void ExpandVACopyInst(VACopyInst *Inst) {
146164
// ExpandVarArgCall() converts a CallInst or InvokeInst to expand out
147165
// of varargs. It returns whether the module was modified.
148166
template <class InstType>
149-
static bool ExpandVarArgCall(InstType *Call, DataLayout *DL) {
167+
static bool ExpandVarArgCall(Module *M, InstType *Call, DataLayout *DL) {
150168
FunctionType *FuncType = cast<FunctionType>(
151169
Call->getCalledValue()->getType()->getPointerElementType());
152170
if (!FuncType->isFunctionVarArg())
153171
return false;
172+
if (auto *F = dyn_cast<Function>(Call->getCalledValue()))
173+
if (isEmscriptenJSArgsFunc(M, F->getName()))
174+
return false;
154175

155176
Function *F = Call->getParent()->getParent();
156-
Module *M = F->getParent();
157177
LLVMContext &Ctx = M->getContext();
158178

159179
SmallVector<AttributeSet, 8> Attrs;
@@ -284,17 +304,15 @@ bool ExpandVarArgs::runOnModule(Module &M) {
284304
Changed = true;
285305
ExpandVACopyInst(VAC);
286306
} else if (auto *Call = dyn_cast<CallInst>(I)) {
287-
Changed |= ExpandVarArgCall(Call, &DL);
307+
Changed |= ExpandVarArgCall(&M, Call, &DL);
288308
} else if (auto *Call = dyn_cast<InvokeInst>(I)) {
289-
Changed |= ExpandVarArgCall(Call, &DL);
309+
Changed |= ExpandVarArgCall(&M, Call, &DL);
290310
}
291311
}
292312
}
293313

294-
if (F->isVarArg()) {
295-
Changed = true;
296-
ExpandVarArgFunc(F);
297-
}
314+
if (F->isVarArg())
315+
Changed |= ExpandVarArgFunc(&M, F);
298316
}
299317

300318
return Changed;
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
; RUN: opt < %s -mtriple=asmjs-unknown-emscripten -expand-varargs -S | FileCheck %s
2+
3+
target datalayout = "p:32:32:32"
4+
5+
%va_list = type i8*
6+
7+
declare void @llvm.va_start(i8*)
8+
declare void @llvm.va_end(i8*)
9+
declare void @llvm.va_copy(i8*, i8*)
10+
11+
declare void @emscripten_asm_const_int(...)
12+
declare void @emscripten_asm_const_double(...)
13+
declare void @emscripten_landingpad(...)
14+
declare void @emscripten_resume(...)
15+
16+
define void @test(i32 %arg) {
17+
call void (...)* @emscripten_asm_const_int(i32 %arg)
18+
call void (...)* @emscripten_asm_const_double(i32 %arg)
19+
call void (...)* @emscripten_landingpad(i32 %arg)
20+
call void (...)* @emscripten_resume(i32 %arg)
21+
ret void
22+
}
23+
; CHECK-LABEL: define void @test(
24+
; CHECK-NEXT: call void (...)* @emscripten_asm_const_int(i32 %arg)
25+
; CHECK-NEXT: call void (...)* @emscripten_asm_const_double(i32 %arg)
26+
; CHECK-NEXT: call void (...)* @emscripten_landingpad(i32 %arg)
27+
; CHECK-NEXT: call void (...)* @emscripten_resume(i32 %arg)
28+
; CHECK-NEXT: ret void

0 commit comments

Comments
 (0)