]> granicus.if.org Git - llvm/commitdiff
[WebAssembly] Fix allocsize attribute in sjlj lowering
authorKeno Fischer <keno@alumni.harvard.edu>
Sat, 3 Aug 2019 21:38:19 +0000 (21:38 +0000)
committerKeno Fischer <keno@alumni.harvard.edu>
Sat, 3 Aug 2019 21:38:19 +0000 (21:38 +0000)
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

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@367765 91177308-0d34-0410-b5e6-96231b3b80d8

lib/Target/WebAssembly/WebAssemblyLowerEmscriptenEHSjLj.cpp
test/CodeGen/WebAssembly/lower-em-sjlj.ll

index 960d5134f6e9a6d50a01d985b9128b39dcf21dac..a002a70845cf347458ae5c924b692cf13d35e854 100644 (file)
@@ -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);
 
index b65af1434ba9b46c5d1f553c3737604eecc0b267..425c4dda6ead8d13320d26ac00e6d5cc0ef088c0 100644 (file)
@@ -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
@@ -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
@@ -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
@@ -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) }