Skip to content
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
27 changes: 19 additions & 8 deletions llvm/docs/LangRef.rst
Original file line number Diff line number Diff line change
Expand Up @@ -969,7 +969,9 @@ an optional ``unnamed_addr`` attribute, a return type, an optional
name, a (possibly empty) argument list (each with optional :ref:`parameter
attributes <paramattrs>`), optional :ref:`function attributes <fnattrs>`,
an optional address space, an optional section, an optional partition,
an optional alignment, an optional :ref:`comdat <langref_comdats>`,
an optional minimum alignment,
an optional preferred alignment,
an optional :ref:`comdat <langref_comdats>`,
an optional :ref:`garbage collector name <gc>`, an optional :ref:`prefix <prefixdata>`,
an optional :ref:`prologue <prologuedata>`,
an optional :ref:`personality <personalityfn>`,
Expand All @@ -983,8 +985,8 @@ Syntax::
<ResultType> @<FunctionName> ([argument list])
[(unnamed_addr|local_unnamed_addr)] [AddrSpace] [fn Attrs]
[section "name"] [partition "name"] [comdat [($name)]] [align N]
[gc] [prefix Constant] [prologue Constant] [personality Constant]
(!name !N)* { ... }
[prefalign N] [gc] [prefix Constant] [prologue Constant]
[personality Constant] (!name !N)* { ... }

The argument list is a comma-separated sequence of arguments where each
argument is of the following form:
Expand Down Expand Up @@ -1034,11 +1036,20 @@ LLVM allows an explicit section to be specified for functions. If the
target supports it, it will emit functions to the section specified.
Additionally, the function can be placed in a COMDAT.

An explicit alignment may be specified for a function. If not present,
or if the alignment is set to zero, the alignment of the function is set
by the target to whatever it feels convenient. If an explicit alignment
is specified, the function is forced to have at least that much
alignment. All alignments must be a power of 2.
An explicit minimum alignment (``align``) may be specified for a
function. If not present, or if the alignment is set to zero, the
alignment of the function is set according to the preferred alignment
rules described below. If an explicit minimum alignment is specified, the
function is forced to have at least that much alignment. All alignments
must be a power of 2.

An explicit preferred alignment (``prefalign``) may also be specified for
a function (definitions only, and must be a power of 2). If a function
does not have a preferred alignment attribute, the preferred alignment
is determined in a target-specific way. The preferred alignment, if
provided, is treated as a hint; the final alignment of the function will
generally be set to a value somewhere between the minimum alignment and
the preferred alignment.

If the ``unnamed_addr`` attribute is given, the address is known to not
be significant and two identical functions can be merged.
Expand Down
2 changes: 1 addition & 1 deletion llvm/include/llvm/AsmParser/LLParser.h
Original file line number Diff line number Diff line change
Expand Up @@ -311,7 +311,7 @@ namespace llvm {
GlobalValueSummary::ImportKind &Res);
void parseOptionalDLLStorageClass(unsigned &Res);
bool parseOptionalCallingConv(unsigned &CC);
bool parseOptionalAlignment(MaybeAlign &Alignment,
bool parseOptionalAlignment(lltok::Kind KW, MaybeAlign &Alignment,
bool AllowParens = false);
bool parseOptionalCodeModel(CodeModel::Model &model);
bool parseOptionalDerefAttrBytes(lltok::Kind AttrKind, uint64_t &Bytes);
Expand Down
1 change: 1 addition & 0 deletions llvm/include/llvm/AsmParser/LLToken.h
Original file line number Diff line number Diff line change
Expand Up @@ -130,6 +130,7 @@ enum Kind {
kw_prefix,
kw_prologue,
kw_c,
kw_prefalign,

kw_cc,
kw_ccc,
Expand Down
9 changes: 8 additions & 1 deletion llvm/include/llvm/IR/Function.h
Original file line number Diff line number Diff line change
Expand Up @@ -85,7 +85,8 @@ class LLVM_ABI Function : public GlobalObject, public ilist_node<Function> {
unsigned BlockNumEpoch = 0;

mutable Argument *Arguments = nullptr; ///< The formal arguments
size_t NumArgs;
uint32_t NumArgs;
MaybeAlign PreferredAlign;
std::unique_ptr<ValueSymbolTable>
SymTab; ///< Symbol table of args/instructions
AttributeList AttributeSets; ///< Parameter attributes
Expand Down Expand Up @@ -1043,6 +1044,12 @@ class LLVM_ABI Function : public GlobalObject, public ilist_node<Function> {
/// defined.
void setAlignment(MaybeAlign Align) { GlobalObject::setAlignment(Align); }

/// Returns the prefalign of the given function.
MaybeAlign getPreferredAlignment() const { return PreferredAlign; }

/// Sets the prefalign attribute of the Function.
void setPreferredAlignment(MaybeAlign Align) { PreferredAlign = Align; }

/// Return the value for vscale based on the vscale_range attribute or 0 when
/// unknown.
unsigned getVScaleValue() const;
Expand Down
1 change: 1 addition & 0 deletions llvm/lib/AsmParser/LLLexer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -625,6 +625,7 @@ lltok::Kind LLLexer::LexIdentifier() {
KEYWORD(gc);
KEYWORD(prefix);
KEYWORD(prologue);
KEYWORD(prefalign);

KEYWORD(no_sanitize_address);
KEYWORD(no_sanitize_hwaddress);
Expand Down
23 changes: 13 additions & 10 deletions llvm/lib/AsmParser/LLParser.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1452,7 +1452,7 @@ bool LLParser::parseGlobal(const std::string &Name, unsigned NameID,
return true;
} else if (Lex.getKind() == lltok::kw_align) {
MaybeAlign Alignment;
if (parseOptionalAlignment(Alignment))
if (parseOptionalAlignment(lltok::kw_align, Alignment))
return true;
if (Alignment)
GV->setAlignment(*Alignment);
Expand Down Expand Up @@ -1551,7 +1551,7 @@ bool LLParser::parseEnumAttribute(Attribute::AttrKind Attr, AttrBuilder &B,
return true;
Alignment = Align(Value);
} else {
if (parseOptionalAlignment(Alignment, true))
if (parseOptionalAlignment(lltok::kw_align, Alignment, true))
return true;
}
B.addAlignmentAttr(Alignment);
Expand Down Expand Up @@ -2394,10 +2394,11 @@ bool LLParser::parseOptionalFunctionMetadata(Function &F) {

/// parseOptionalAlignment
/// ::= /* empty */
/// ::= 'align' 4
bool LLParser::parseOptionalAlignment(MaybeAlign &Alignment, bool AllowParens) {
/// ::= KW 4
bool LLParser::parseOptionalAlignment(lltok::Kind KW, MaybeAlign &Alignment,
bool AllowParens) {
Alignment = std::nullopt;
if (!EatIfPresent(lltok::kw_align))
if (!EatIfPresent(KW))
return false;
LocTy AlignLoc = Lex.getLoc();
uint64_t Value = 0;
Expand Down Expand Up @@ -2707,7 +2708,7 @@ bool LLParser::parseOptionalCommaAlign(MaybeAlign &Alignment,
if (Lex.getKind() != lltok::kw_align)
return error(Lex.getLoc(), "expected metadata or 'align'");

if (parseOptionalAlignment(Alignment))
if (parseOptionalAlignment(lltok::kw_align, Alignment))
return true;
}

Expand Down Expand Up @@ -6717,7 +6718,7 @@ bool LLParser::parseFunctionHeader(Function *&Fn, bool IsDefine,
LocTy BuiltinLoc;
std::string Section;
std::string Partition;
MaybeAlign Alignment;
MaybeAlign Alignment, PrefAlignment;
std::string GC;
GlobalValue::UnnamedAddr UnnamedAddr = GlobalValue::UnnamedAddr::None;
unsigned AddrSpace = 0;
Expand All @@ -6734,7 +6735,8 @@ bool LLParser::parseFunctionHeader(Function *&Fn, bool IsDefine,
(EatIfPresent(lltok::kw_section) && parseStringConstant(Section)) ||
(EatIfPresent(lltok::kw_partition) && parseStringConstant(Partition)) ||
parseOptionalComdat(FunctionName, C) ||
parseOptionalAlignment(Alignment) ||
parseOptionalAlignment(lltok::kw_align, Alignment) ||
parseOptionalAlignment(lltok::kw_prefalign, PrefAlignment) ||
(EatIfPresent(lltok::kw_gc) && parseStringConstant(GC)) ||
(EatIfPresent(lltok::kw_prefix) && parseGlobalTypeAndValue(Prefix)) ||
(EatIfPresent(lltok::kw_prologue) && parseGlobalTypeAndValue(Prologue)) ||
Expand Down Expand Up @@ -6836,6 +6838,7 @@ bool LLParser::parseFunctionHeader(Function *&Fn, bool IsDefine,
Fn->setUnnamedAddr(UnnamedAddr);
if (Alignment)
Fn->setAlignment(*Alignment);
Fn->setPreferredAlignment(PrefAlignment);
Fn->setSection(Section);
Fn->setPartition(Partition);
Fn->setComdat(C);
Expand Down Expand Up @@ -8458,7 +8461,7 @@ int LLParser::parseAlloc(Instruction *&Inst, PerFunctionState &PFS) {
bool AteExtraComma = false;
if (EatIfPresent(lltok::comma)) {
if (Lex.getKind() == lltok::kw_align) {
if (parseOptionalAlignment(Alignment))
if (parseOptionalAlignment(lltok::kw_align, Alignment))
return true;
if (parseOptionalCommaAddrSpace(AddrSpace, ASLoc, AteExtraComma))
return true;
Expand All @@ -8473,7 +8476,7 @@ int LLParser::parseAlloc(Instruction *&Inst, PerFunctionState &PFS) {
return true;
if (EatIfPresent(lltok::comma)) {
if (Lex.getKind() == lltok::kw_align) {
if (parseOptionalAlignment(Alignment))
if (parseOptionalAlignment(lltok::kw_align, Alignment))
return true;
if (parseOptionalCommaAddrSpace(AddrSpace, ASLoc, AteExtraComma))
return true;
Expand Down
7 changes: 7 additions & 0 deletions llvm/lib/Bitcode/Reader/BitcodeReader.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -4385,6 +4385,13 @@ Error BitcodeReader::parseFunctionRecord(ArrayRef<uint64_t> Record) {
Func->setPartition(StringRef(Strtab.data() + Record[17], Record[18]));
}

if (Record.size() > 19) {
MaybeAlign PrefAlignment;
if (Error Err = parseAlignmentValue(Record[19], PrefAlignment))
return Err;
Func->setPreferredAlignment(PrefAlignment);
}

ValueList.push_back(Func, getVirtualTypeID(Func->getType(), FTyID));

if (OperandInfo.PersonalityFn || OperandInfo.Prefix || OperandInfo.Prologue)
Expand Down
4 changes: 3 additions & 1 deletion llvm/lib/Bitcode/Writer/BitcodeWriter.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1644,7 +1644,8 @@ void ModuleBitcodeWriter::writeModuleInfo() {
// FUNCTION: [strtab offset, strtab size, type, callingconv, isproto,
// linkage, paramattrs, alignment, section, visibility, gc,
// unnamed_addr, prologuedata, dllstorageclass, comdat,
// prefixdata, personalityfn, DSO_Local, addrspace]
// prefixdata, personalityfn, DSO_Local, addrspace,
// partition_strtab, partition_size, prefalign]
Vals.push_back(addToStrtab(F.getName()));
Vals.push_back(F.getName().size());
Vals.push_back(VE.getTypeID(F.getFunctionType()));
Expand All @@ -1671,6 +1672,7 @@ void ModuleBitcodeWriter::writeModuleInfo() {
Vals.push_back(F.getAddressSpace());
Vals.push_back(addToStrtab(F.getPartition()));
Vals.push_back(F.getPartition().size());
Vals.push_back(getEncodedAlign(F.getPreferredAlignment()));

unsigned AbbrevToUse = 0;
Stream.EmitRecord(bitc::MODULE_CODE_FUNCTION, Vals, AbbrevToUse);
Expand Down
2 changes: 2 additions & 0 deletions llvm/lib/IR/AsmWriter.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -4169,6 +4169,8 @@ void AssemblyWriter::printFunction(const Function *F) {
maybePrintComdat(Out, *F);
if (MaybeAlign A = F->getAlign())
Out << " align " << A->value();
if (MaybeAlign A = F->getPreferredAlignment())
Out << " prefalign " << A->value();
if (F->hasGC())
Out << " gc \"" << F->getGC() << '"';
if (F->hasPrefixData()) {
Expand Down
14 changes: 14 additions & 0 deletions llvm/test/Bitcode/compatibility.ll
Original file line number Diff line number Diff line change
Expand Up @@ -759,6 +759,20 @@ declare void @f.align4() align 4
declare void @f.align8() align 8
; CHECK: declare void @f.align8() align 8

; Functions -- prefalign
define void @f.prefalign2() prefalign 2 {
ret void
}
; CHECK: define void @f.prefalign2() prefalign 2
define void @f.prefalign4() prefalign 4 {
ret void
}
; CHECK: define void @f.prefalign4() prefalign 4
define void @f.prefalign8() prefalign 8 {
ret void
}
; CHECK: define void @f.prefalign8() prefalign 8

; Functions -- GC
declare void @f.gcshadow() gc "shadow-stack"
; CHECK: declare void @f.gcshadow() gc "shadow-stack"
Expand Down