.. _attr_align:
-``align <n>``
+``align <n>`` or ``align(<n>)``
This indicates that the pointer value may be assumed by the optimizer to
have the specified alignment. If the pointer value does not have the
specified alignment, behavior is undefined.
}
case lltok::kw_align: {
MaybeAlign Alignment;
- if (ParseOptionalAlignment(Alignment))
+ if (ParseOptionalAlignment(Alignment, true))
return true;
B.addAlignmentAttr(Alignment);
continue;
/// ParseOptionalAlignment
/// ::= /* empty */
/// ::= 'align' 4
-bool LLParser::ParseOptionalAlignment(MaybeAlign &Alignment) {
+bool LLParser::ParseOptionalAlignment(MaybeAlign &Alignment, bool AllowParens) {
Alignment = None;
if (!EatIfPresent(lltok::kw_align))
return false;
LocTy AlignLoc = Lex.getLoc();
uint32_t Value = 0;
+
+ LocTy ParenLoc = Lex.getLoc();
+ bool HaveParens = false;
+ if (AllowParens) {
+ if (EatIfPresent(lltok::lparen))
+ HaveParens = true;
+ }
+
if (ParseUInt32(Value))
return true;
+
+ if (HaveParens && !EatIfPresent(lltok::rparen))
+ return Error(ParenLoc, "expected ')'");
+
if (!isPowerOf2_32(Value))
return Error(AlignLoc, "alignment is not a power of two");
if (Value > Value::MaximumAlignment)
void ParseOptionalVisibility(unsigned &Res);
void ParseOptionalDLLStorageClass(unsigned &Res);
bool ParseOptionalCallingConv(unsigned &CC);
- bool ParseOptionalAlignment(MaybeAlign &Alignment);
+ bool ParseOptionalAlignment(MaybeAlign &Alignment,
+ bool AllowParens = false);
bool ParseOptionalDerefAttrBytes(lltok::Kind AttrKind, uint64_t &Bytes);
bool ParseScopeAndOrdering(bool isAtomic, SyncScope::ID &SSID,
AtomicOrdering &Ordering);
--- /dev/null
+; RUN: not llvm-as < %s 2>&1 | FileCheck %s
+; Test parse errors when using form of align attribute with parentheses
+
+; CHECK: <stdin>:[[@LINE+1]]:38: error: expected ')'
+define void @missing_rparen(i8* align(4 %ptr) {
+ ret void
+}
--- /dev/null
+; RUN: not llvm-as < %s 2>&1 | FileCheck %s
+; Test parse errors when using form of align attribute with parentheses
+
+; CHECK: <stdin>:[[@LINE+1]]:42: error: expected '{' in function body
+define void @missing_Lparen(i8* align 4) %ptr) {
+ ret void
+}
--- /dev/null
+; RUN: not llvm-as < %s 2>&1 | FileCheck %s
+; Test parse errors when using form of align attribute with parentheses
+
+; CHECK: <stdin>:[[@LINE+1]]:39: error: expected integer
+define void @missing_value(i8* align () %ptr) {
+ ret void
+}
--- /dev/null
+; RUN: llvm-as < %s | llvm-dis | llvm-as | llvm-dis | FileCheck %s
+
+; Test that align(N) is accepted as an alternative syntax to align N
+
+; CHECK: define void @param_align4(i8* align 4 %ptr) {
+define void @param_align4(i8* align(4) %ptr) {
+ ret void
+}
+
+; CHECK: define void @param_align128(i8* align 128 %0) {
+define void @param_align128(i8* align(128)) {
+ ret void
+}