Skip to content

Commit

Permalink
Do not call LLVMSetAlignment with 0 alignment.
Browse files Browse the repository at this point in the history
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.
  • Loading branch information
matthewseaman committed Feb 17, 2021
1 parent b616249 commit 493672e
Show file tree
Hide file tree
Showing 2 changed files with 13 additions and 5 deletions.
16 changes: 12 additions & 4 deletions Sources/LLVM/IRBuilder.swift
Original file line number Diff line number Diff line change
Expand Up @@ -1057,7 +1057,9 @@ extension IRBuilder {
} else {
allocaInst = LLVMBuildAlloca(llvm, type.asLLVM(), name)!
}
LLVMSetAlignment(allocaInst, alignment.rawValue)
if !alignment.isZero {
LLVMSetAlignment(allocaInst, alignment.rawValue)
}
return allocaInst
}

Expand All @@ -1077,7 +1079,9 @@ extension IRBuilder {
let storeInst = LLVMBuildStore(llvm, val.asLLVM(), ptr.asLLVM())!
LLVMSetOrdering(storeInst, ordering.llvm)
LLVMSetVolatile(storeInst, volatile.llvm)
LLVMSetAlignment(storeInst, alignment.rawValue)
if !alignment.isZero {
LLVMSetAlignment(storeInst, alignment.rawValue)
}
return storeInst
}

Expand All @@ -1098,7 +1102,9 @@ extension IRBuilder {
let loadInst = LLVMBuildLoad2(llvm, type.asLLVM(), ptr.asLLVM(), name)!
LLVMSetOrdering(loadInst, ordering.llvm)
LLVMSetVolatile(loadInst, volatile.llvm)
LLVMSetAlignment(loadInst, alignment.rawValue)
if !alignment.isZero {
LLVMSetAlignment(loadInst, alignment.rawValue)
}
return loadInst
}

Expand Down Expand Up @@ -1941,7 +1947,9 @@ extension IRBuilder {
let loadInst = LLVMBuildLoad(llvm, ptr.asLLVM(), name)!
LLVMSetOrdering(loadInst, ordering.llvm)
LLVMSetVolatile(loadInst, volatile.llvm)
LLVMSetAlignment(loadInst, alignment.rawValue)
if !alignment.isZero {
LLVMSetAlignment(loadInst, alignment.rawValue)
}
return loadInst
}

Expand Down
2 changes: 1 addition & 1 deletion Tests/LLVMTests/IRMetadataSpec.swift
Original file line number Diff line number Diff line change
Expand Up @@ -180,7 +180,7 @@ class IRMetadataSpec : XCTestCase {
IntType.int32.constant(0), // .s
])
// B->a.s = 42
// IRSIMPLETBAA-NEXT: store i16 42, i16* %1, !tbaa [[AccessTag:![0-9]+]]
// IRSIMPLETBAA-NEXT: store i16 42, i16* %1, align 2, !tbaa [[AccessTag:![0-9]+]]
let si = builder.buildStore(IntType.int16.constant(42), to: field)
// IRSIMPLETBAA-NEXT: ret void
builder.buildRetVoid()
Expand Down

0 comments on commit 493672e

Please sign in to comment.