Skip to content

Commit 493672e

Browse files
committed
Do not call LLVMSetAlignment with 0 alignment.
A recent version of LLVM removed implicit alignments from alloca, load, and store. This means that an "align n" must be present on those instructions, although one will be automatically generated by LLVMBuildAlloca and similar instructions. As part of this, LLVM changed the behavior of LLVMSetAlignment to wrap the alignment in an Align rather than a MaybeAlign. As a result, when an alignment 0 is explicitly set, LLVM assumes it is greater than 0 and takes the log2 of it. The shortcut algorithm for log2 (e.g. 31 - leading zero bit count) results in an overflow when the alignment is 0. This causes the module verifier to fail. Solution: Let the default alignment be calculated and don't explicitly set it when no explicit alignment is specified.
1 parent b616249 commit 493672e

File tree

2 files changed

+13
-5
lines changed

2 files changed

+13
-5
lines changed

Sources/LLVM/IRBuilder.swift

Lines changed: 12 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1057,7 +1057,9 @@ extension IRBuilder {
10571057
} else {
10581058
allocaInst = LLVMBuildAlloca(llvm, type.asLLVM(), name)!
10591059
}
1060-
LLVMSetAlignment(allocaInst, alignment.rawValue)
1060+
if !alignment.isZero {
1061+
LLVMSetAlignment(allocaInst, alignment.rawValue)
1062+
}
10611063
return allocaInst
10621064
}
10631065

@@ -1077,7 +1079,9 @@ extension IRBuilder {
10771079
let storeInst = LLVMBuildStore(llvm, val.asLLVM(), ptr.asLLVM())!
10781080
LLVMSetOrdering(storeInst, ordering.llvm)
10791081
LLVMSetVolatile(storeInst, volatile.llvm)
1080-
LLVMSetAlignment(storeInst, alignment.rawValue)
1082+
if !alignment.isZero {
1083+
LLVMSetAlignment(storeInst, alignment.rawValue)
1084+
}
10811085
return storeInst
10821086
}
10831087

@@ -1098,7 +1102,9 @@ extension IRBuilder {
10981102
let loadInst = LLVMBuildLoad2(llvm, type.asLLVM(), ptr.asLLVM(), name)!
10991103
LLVMSetOrdering(loadInst, ordering.llvm)
11001104
LLVMSetVolatile(loadInst, volatile.llvm)
1101-
LLVMSetAlignment(loadInst, alignment.rawValue)
1105+
if !alignment.isZero {
1106+
LLVMSetAlignment(loadInst, alignment.rawValue)
1107+
}
11021108
return loadInst
11031109
}
11041110

@@ -1941,7 +1947,9 @@ extension IRBuilder {
19411947
let loadInst = LLVMBuildLoad(llvm, ptr.asLLVM(), name)!
19421948
LLVMSetOrdering(loadInst, ordering.llvm)
19431949
LLVMSetVolatile(loadInst, volatile.llvm)
1944-
LLVMSetAlignment(loadInst, alignment.rawValue)
1950+
if !alignment.isZero {
1951+
LLVMSetAlignment(loadInst, alignment.rawValue)
1952+
}
19451953
return loadInst
19461954
}
19471955

Tests/LLVMTests/IRMetadataSpec.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -180,7 +180,7 @@ class IRMetadataSpec : XCTestCase {
180180
IntType.int32.constant(0), // .s
181181
])
182182
// B->a.s = 42
183-
// IRSIMPLETBAA-NEXT: store i16 42, i16* %1, !tbaa [[AccessTag:![0-9]+]]
183+
// IRSIMPLETBAA-NEXT: store i16 42, i16* %1, align 2, !tbaa [[AccessTag:![0-9]+]]
184184
let si = builder.buildStore(IntType.int16.constant(42), to: field)
185185
// IRSIMPLETBAA-NEXT: ret void
186186
builder.buildRetVoid()

0 commit comments

Comments
 (0)