Skip to content

Commit

Permalink
[WebAssembly] Fix allocsize attribute in sjlj lowering
Browse files Browse the repository at this point in the history
Summary:
The allocsize attribute refers to call parameters by index.
Thus, when we add the extra parameter in sjlj lowering, we
need to increment the referenced paramater in the allocsize
attribute to avoid angering the Verifier.

Reviewed By: aheejin
Differential Revision: https://reviews.llvm.org/D65470

llvm-svn: 367765
  • Loading branch information
Keno committed Aug 3, 2019
1 parent 3daccaa commit 3c805d1
Show file tree
Hide file tree
Showing 2 changed files with 31 additions and 3 deletions.
15 changes: 14 additions & 1 deletion llvm/lib/Target/WebAssembly/WebAssemblyLowerEmscriptenEHSjLj.cpp
Expand Up @@ -432,9 +432,22 @@ Value *WebAssemblyLowerEmscriptenEHSjLj::wrapInvoke(CallOrInvoke *CI) {
for (unsigned I = 0, E = CI->getNumArgOperands(); I < E; ++I)
ArgAttributes.push_back(InvokeAL.getParamAttributes(I));

AttrBuilder FnAttrs(InvokeAL.getFnAttributes());
if (FnAttrs.contains(Attribute::AllocSize)) {
// The allocsize attribute (if any) referes to parameters by index and needs
// to be adjusted.
unsigned SizeArg;
Optional<unsigned> NEltArg;
std::tie(SizeArg, NEltArg) = FnAttrs.getAllocSizeArgs();
SizeArg += 1;
if (NEltArg.hasValue())
NEltArg = NEltArg.getValue() + 1;
FnAttrs.addAllocSizeAttr(SizeArg, NEltArg);
}

// Reconstruct the AttributesList based on the vector we constructed.
AttributeList NewCallAL =
AttributeList::get(C, InvokeAL.getFnAttributes(),
AttributeList::get(C, AttributeSet::get(C, FnAttrs),
InvokeAL.getRetAttributes(), ArgAttributes);
NewCall->setAttributes(NewCallAL);

Expand Down
19 changes: 17 additions & 2 deletions llvm/test/CodeGen/WebAssembly/lower-em-sjlj.ll
Expand Up @@ -94,7 +94,7 @@ entry:
}

; Test a case when a function call is within try-catch, after a setjmp
define hidden void @exception_and_longjmp() #3 personality i8* bitcast (i32 (...)* @__gxx_personality_v0 to i8*) {
define hidden void @exception_and_longjmp() personality i8* bitcast (i32 (...)* @__gxx_personality_v0 to i8*) {
; CHECK-LABEL: @exception_and_longjmp
entry:
%buf = alloca [1 x %struct.__jmp_buf_tag], align 16
Expand Down Expand Up @@ -185,7 +185,7 @@ entry:
call void @longjmp(%struct.__jmp_buf_tag* %arraydecay, i32 5) #1
unreachable
; CHECK: %[[ARRAYDECAY:.*]] = getelementptr inbounds
; CHECK-NEXT: call void @emscripten_longjmp_jmpbuf(%struct.__jmp_buf_tag* %[[ARRAYDECAY]], i32 5) #1
; CHECK-NEXT: call void @emscripten_longjmp_jmpbuf(%struct.__jmp_buf_tag* %[[ARRAYDECAY]], i32 5)
}

; Test inline asm handling
Expand All @@ -203,6 +203,19 @@ entry:
ret void
}

; Test that the allocsize attribute is being transformed properly
declare i8 *@allocator(i32, %struct.__jmp_buf_tag*) #3
define hidden i8 *@allocsize() {
; CHECK-LABEL: @allocsize
entry:
%buf = alloca [1 x %struct.__jmp_buf_tag], align 16
%arraydecay = getelementptr inbounds [1 x %struct.__jmp_buf_tag], [1 x %struct.__jmp_buf_tag]* %buf, i32 0, i32 0
%call = call i32 @setjmp(%struct.__jmp_buf_tag* %arraydecay) #0
; CHECK: i8* @"__invoke_i8*_i32_%struct.__jmp_buf_tag*"([[ARGS:.*]]) #[[ALLOCSIZE_ATTR:[0-9]+]]
%alloc = call i8* @allocator(i32 20, %struct.__jmp_buf_tag* %arraydecay) #3
ret i8 *%alloc
}

declare void @foo()
; Function Attrs: returns_twice
declare i32 @setjmp(%struct.__jmp_buf_tag*) #0
Expand All @@ -227,3 +240,5 @@ declare void @free(i8*)
attributes #0 = { returns_twice }
attributes #1 = { noreturn }
attributes #2 = { nounwind }
attributes #3 = { allocsize(0) }
; CHECK: attributes #[[ALLOCSIZE_ATTR]] = { allocsize(1) }

0 comments on commit 3c805d1

Please sign in to comment.