Skip to content

Commit ffaa8a8

Browse files
committedApr 27, 2018
[IR] Do not assume that function pointers are aligned
Summary: The value tracking analysis uses function alignment to infer that the least significant bits of function pointers are known to be zero. Unfortunately, this is not correct for ARM targets: the least significant bit of a function pointer stores the ARM/Thumb state information (i.e., the LSB is set for Thumb functions and cleared for ARM functions). The original approach (https://reviews.llvm.org/D44781) introduced a new field for function pointer alignment in the DataLayout structure to address this. But it seems unlikely that optimizations based on function pointer alignment would bring much benefit in practice to justify the additional maintenance burden, so this patch simply assumes that function pointer alignment is always unknown. Reviewers: javed.absar, efriedma Reviewed By: efriedma Subscribers: kristof.beyls, llvm-commits, hfinkel, rogfer01 Differential Revision: https://reviews.llvm.org/D46110 llvm-svn: 331025
1 parent d4349f3 commit ffaa8a8

File tree

2 files changed

+22
-0
lines changed

2 files changed

+22
-0
lines changed
 

Diff for: ‎llvm/lib/IR/Value.cpp

+4
Original file line numberDiff line numberDiff line change
@@ -685,6 +685,10 @@ unsigned Value::getPointerAlignment(const DataLayout &DL) const {
685685

686686
unsigned Align = 0;
687687
if (auto *GO = dyn_cast<GlobalObject>(this)) {
688+
// Don't make any assumptions about function pointer alignment. Some
689+
// targets use the LSBs to store additional information.
690+
if (isa<Function>(GO))
691+
return 0;
688692
Align = GO->getAlignment();
689693
if (Align == 0) {
690694
if (auto *GVar = dyn_cast<GlobalVariable>(GO)) {

Diff for: ‎llvm/test/Analysis/ValueTracking/func-ptr-lsb.ll

+18
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
; RUN: opt -instcombine -S < %s | FileCheck %s
2+
3+
target datalayout = "e-p:32:32-n32-S64"
4+
5+
; CHECK-LABEL: @foo_ptr
6+
; CHECK: and
7+
define i32 @foo_ptr() {
8+
entry:
9+
; Even though the address of @foo is aligned, we cannot assume that the
10+
; pointer has the same alignment. This is not true for e.g. ARM targets
11+
; which store ARM/Thumb state in the LSB
12+
ret i32 and (i32 ptrtoint (void ()* @foo to i32), i32 -4)
13+
}
14+
15+
define internal void @foo() align 16 {
16+
entry:
17+
ret void
18+
}

0 commit comments

Comments
 (0)
Please sign in to comment.