Skip to content

__declspec(noshrinkwrap) support #147397

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 1 commit into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 7 additions & 0 deletions clang/include/clang/Basic/Attr.td
Original file line number Diff line number Diff line change
Expand Up @@ -5190,3 +5190,10 @@ def NonString : InheritableAttr {
let Subjects = SubjectList<[Var, Field]>;
let Documentation = [NonStringDocs];
}

def NoShrinkWrapping : InheritableAttr {
let Spellings = [Declspec<"noshrinkwrap">];
let Subjects = SubjectList<[Function]>;
let Documentation = [NoShrinkWrappingDocs];
let SimpleHandler = 1;
}
8 changes: 8 additions & 0 deletions clang/include/clang/Basic/AttrDocs.td
Original file line number Diff line number Diff line change
Expand Up @@ -9427,3 +9427,11 @@ diagnostics with code like:
__attribute__((nonstring)) char NotAStr[3] = "foo"; // Not diagnosed
}];
}

def NoShrinkWrappingDocs : Documentation {
let Category = DocCatFunction;
let Content = [{
The ``__declspec(noshrinkwrap)`` attribute disables the shrinkwrapping
process for this function.
}];
}
4 changes: 4 additions & 0 deletions clang/lib/CodeGen/CodeGenModule.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2642,6 +2642,10 @@ void CodeGenModule::SetLLVMFunctionAttributesForDefinition(const Decl *D,
else if (isStackProtectorOn(LangOpts, getTriple(), LangOptions::SSPReq))
B.addAttribute(llvm::Attribute::StackProtectReq);

if (D && D->hasAttr<NoShrinkWrappingAttr>()) {
B.addAttribute(llvm::Attribute::NoShrinkWrap);
}

if (!D) {
// Non-entry HLSL functions must always be inlined.
if (getLangOpts().HLSL && !F->hasFnAttribute(llvm::Attribute::NoInline))
Expand Down
4 changes: 4 additions & 0 deletions clang/lib/Sema/SemaDeclAttr.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -7869,6 +7869,10 @@ ProcessDeclAttribute(Sema &S, Scope *scope, Decl *D, const ParsedAttr &AL,
case ParsedAttr::AT_VTablePointerAuthentication:
handleVTablePointerAuthentication(S, D, AL);
break;

case ParsedAttr::AT_NoShrinkWrapping:
handleSimpleAttribute<NoShrinkWrappingAttr>(S, D, AL);
break;
}
}

Expand Down
11 changes: 11 additions & 0 deletions clang/test/CodeGen/declspec-noshrinkwrap.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
// RUN: %clang_cc1 -fdeclspec -emit-llvm %s -o - | FileCheck %s

// Ensure that declspec results in a llvm function attribute
__declspec(noshrinkwrap)
int square(int a) {
return a*a;
}

// CHECK: Function Attrs: {{.*}} noshrinkwrap
// CHECK-LABEL: @square
// CHECK: attributes #0 {{.*}} noshrinkwrap
1 change: 1 addition & 0 deletions llvm/include/llvm/Bitcode/LLVMBitCodes.h
Original file line number Diff line number Diff line change
Expand Up @@ -799,6 +799,7 @@ enum AttributeKindCodes {
ATTR_KIND_SANITIZE_TYPE = 101,
ATTR_KIND_CAPTURES = 102,
ATTR_KIND_DEAD_ON_RETURN = 103,
ATTR_KIND_NO_SHRINKWRAP = 104,
};

enum ComdatSelectionKindCodes {
Expand Down
3 changes: 3 additions & 0 deletions llvm/include/llvm/IR/Attributes.td
Original file line number Diff line number Diff line change
Expand Up @@ -402,6 +402,9 @@ def MarkedForWindowsSecureHotPatching
def AllowDirectAccessInHotPatchFunction
: StrBoolAttr<"allow_direct_access_in_hot_patch_function">;

/// Function should not be shrinkwrapped
def NoShrinkWrap : EnumAttr<"noshrinkwrap", IntersectPreserve, [FnAttr]>;

/// Target-independent string attributes.
def LessPreciseFPMAD : StrBoolAttr<"less-precise-fpmad">;
def NoInfsFPMath : StrBoolAttr<"no-infs-fp-math">;
Expand Down
2 changes: 2 additions & 0 deletions llvm/lib/Bitcode/Reader/BitcodeReader.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2246,6 +2246,8 @@ static Attribute::AttrKind getAttrFromCode(uint64_t Code) {
return Attribute::Captures;
case bitc::ATTR_KIND_DEAD_ON_RETURN:
return Attribute::DeadOnReturn;
case bitc::ATTR_KIND_NO_SHRINKWRAP:
return Attribute::NoShrinkWrap;
}
}

Expand Down
2 changes: 2 additions & 0 deletions llvm/lib/Bitcode/Writer/BitcodeWriter.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -946,6 +946,8 @@ static uint64_t getAttrKindEncoding(Attribute::AttrKind Kind) {
return bitc::ATTR_KIND_CAPTURES;
case Attribute::DeadOnReturn:
return bitc::ATTR_KIND_DEAD_ON_RETURN;
case Attribute::NoShrinkWrap:
return bitc::ATTR_KIND_NO_SHRINKWRAP;
case Attribute::EndAttrKinds:
llvm_unreachable("Can not encode end-attribute kinds marker.");
case Attribute::None:
Expand Down
3 changes: 3 additions & 0 deletions llvm/lib/CodeGen/ShrinkWrap.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1013,6 +1013,9 @@ PreservedAnalyses ShrinkWrapPass::run(MachineFunction &MF,
bool ShrinkWrapImpl::isShrinkWrapEnabled(const MachineFunction &MF) {
const TargetFrameLowering *TFI = MF.getSubtarget().getFrameLowering();

if (MF.getFunction().hasFnAttribute(Attribute::NoShrinkWrap))
return false;

switch (EnableShrinkWrapOpt) {
case cl::BOU_UNSET:
return TFI->enableShrinkWrapping(MF) &&
Expand Down
1 change: 1 addition & 0 deletions llvm/lib/Transforms/Utils/CodeExtractor.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -981,6 +981,7 @@ Function *CodeExtractor::constructFunctionDeclaration(
case Attribute::MustProgress:
case Attribute::NoProfile:
case Attribute::SkipProfile:
case Attribute::NoShrinkWrap:
break;
// These attributes cannot be applied to functions.
case Attribute::Alignment:
Expand Down
106 changes: 106 additions & 0 deletions llvm/test/CodeGen/AArch64/arm64-shrink-wrapping-noshrinkwrap.ll
Original file line number Diff line number Diff line change
@@ -0,0 +1,106 @@
; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
; RUN: llc -debugify-and-strip-all-safe %s -o - -mtriple=arm64-apple-ios -enable-shrink-wrap=true -disable-post-ra -frame-pointer=non-leaf | FileCheck %s --check-prefix=ENABLE
; RUN: llc -debugify-and-strip-all-safe %s -o - -enable-shrink-wrap=false -disable-post-ra -frame-pointer=non-leaf | FileCheck %s --check-prefix=DISABLE
; RUN: llc -debugify-and-strip-all-safe %s -o - -mtriple=arm64-apple-ios -enable-shrink-wrap=true -disable-post-ra -frame-pointer=non-leaf | FileCheck %s --check-prefix=NOSHRINK
target datalayout = "e-m:o-i64:64-i128:128-n32:64-S128"
target triple = "arm64-apple-ios"

; Verify that the attribute 'noshrinkwrap' has the same effect as disabling the
; shrinkwrapping entirely.

; Known shrinkwrap example: Simple diamond with a call just on one side.
define i32 @foo(i32 %a, i32 %b) {
; ENABLE-LABEL: foo:
; ENABLE: ; %bb.0:
; ENABLE-NEXT: cmp w0, w1
; ENABLE-NEXT: b.ge LBB0_2
; ENABLE-NEXT: ; %bb.1: ; %true
; ENABLE-NEXT: sub sp, sp, #32
; ENABLE-NEXT: stp x29, x30, [sp, #16] ; 16-byte Folded Spill
; ENABLE-NEXT: add x29, sp, #16
; ENABLE-NEXT: .cfi_def_cfa w29, 16
; ENABLE-NEXT: .cfi_offset w30, -8
; ENABLE-NEXT: .cfi_offset w29, -16
; ENABLE-NEXT: stur w0, [x29, #-4]
; ENABLE-NEXT: sub x1, x29, #4
; ENABLE-NEXT: mov w0, wzr
; ENABLE-NEXT: bl _doSomething
; ENABLE-NEXT: ldp x29, x30, [sp, #16] ; 16-byte Folded Reload
; ENABLE-NEXT: add sp, sp, #32
; ENABLE-NEXT: LBB0_2: ; %false
; ENABLE-NEXT: ret
; ENABLE-LABEL: bar
;
; DISABLE-LABEL: foo:
; DISABLE: ; %bb.0:
; DISABLE-NEXT: sub sp, sp, #32
; DISABLE-NEXT: stp x29, x30, [sp, #16] ; 16-byte Folded Spill
; DISABLE-NEXT: add x29, sp, #16
; DISABLE-NEXT: .cfi_def_cfa w29, 16
; DISABLE-NEXT: .cfi_offset w30, -8
; DISABLE-NEXT: .cfi_offset w29, -16
; DISABLE-NEXT: cmp w0, w1
; DISABLE-NEXT: b.ge LBB0_2
; DISABLE-NEXT: ; %bb.1: ; %true
; DISABLE-NEXT: stur w0, [x29, #-4]
; DISABLE-NEXT: sub x1, x29, #4
; DISABLE-NEXT: mov w0, wzr
; DISABLE-NEXT: bl _doSomething
; DISABLE-NEXT: LBB0_2: ; %false
; DISABLE-NEXT: ldp x29, x30, [sp, #16] ; 16-byte Folded Reload
; DISABLE-NEXT: add sp, sp, #32
; DISABLE-NEXT: ret
; DISABLE-LABEL: bar
%tmp = alloca i32, align 4
%tmp2 = icmp slt i32 %a, %b
br i1 %tmp2, label %true, label %false

true:
store i32 %a, ptr %tmp, align 4
%tmp4 = call i32 @doSomething(i32 0, ptr %tmp)
br label %false

false:
%tmp.0 = phi i32 [ %tmp4, %true ], [ %a, %0 ]
ret i32 %tmp.0
}

; Same code as above but with 'noshrinkwrap' attribute

define i32 @bar(i32 %a, i32 %b) noshrinkwrap {
; NOSHRINK-LABEL: bar:
; NOSHRINK: ; %bb.0:
; NOSHRINK-NEXT: sub sp, sp, #32
; NOSHRINK-NEXT: stp x29, x30, [sp, #16] ; 16-byte Folded Spill
; NOSHRINK-NEXT: add x29, sp, #16
; NOSHRINK-NEXT: .cfi_def_cfa w29, 16
; NOSHRINK-NEXT: .cfi_offset w30, -8
; NOSHRINK-NEXT: .cfi_offset w29, -16
; NOSHRINK-NEXT: cmp w0, w1
; NOSHRINK-NEXT: b.ge LBB1_2
; NOSHRINK-NEXT: ; %bb.1: ; %true
; NOSHRINK-NEXT: stur w0, [x29, #-4]
; NOSHRINK-NEXT: sub x1, x29, #4
; NOSHRINK-NEXT: mov w0, wzr
; NOSHRINK-NEXT: bl _doSomething
; NOSHRINK-NEXT: LBB1_2: ; %false
; NOSHRINK-NEXT: ldp x29, x30, [sp, #16] ; 16-byte Folded Reload
; NOSHRINK-NEXT: add sp, sp, #32
; NOSHRINK-NEXT: ret
%tmp = alloca i32, align 4
%tmp2 = icmp slt i32 %a, %b
br i1 %tmp2, label %true, label %false

true:
store i32 %a, ptr %tmp, align 4
%tmp4 = call i32 @doSomething(i32 0, ptr %tmp)
br label %false

false:
%tmp.0 = phi i32 [ %tmp4, %true ], [ %a, %0 ]
ret i32 %tmp.0
}

; Function Attrs: optsize
declare i32 @doSomething(i32, ptr)

Loading