mirror of
https://github.com/RPCS3/llvm-mirror.git
synced 2024-11-22 02:33:06 +01:00
[IR] Don't assume all functions are 4 byte aligned
In some cases different alignments for function might be used to save space e.g. thumb mode with -Oz will try to use 2 byte function alignment. Similar patch that fixed this in other areas exists here https://reviews.llvm.org/D46110 This was approved previously https://reviews.llvm.org/D55115 (r348215) but when committed it caused failures on the sanitizer buildbots when building llvm with clang (containing this patch). This is now fixed because I've added a check to see if getting the parent module returns null if it does then set the alignment to 0. Differential Revision: https://reviews.llvm.org/D55115 llvm-svn: 348571
This commit is contained in:
parent
6da1480917
commit
377ecd93ee
@ -27,6 +27,7 @@
|
||||
#include "llvm/IR/GlobalAlias.h"
|
||||
#include "llvm/IR/GlobalVariable.h"
|
||||
#include "llvm/IR/Instructions.h"
|
||||
#include "llvm/IR/Module.h"
|
||||
#include "llvm/IR/Operator.h"
|
||||
#include "llvm/IR/PatternMatch.h"
|
||||
#include "llvm/Support/ErrorHandling.h"
|
||||
@ -1077,10 +1078,10 @@ Constant *llvm::ConstantFoldBinaryInstruction(unsigned Opcode, Constant *C1,
|
||||
isa<GlobalValue>(CE1->getOperand(0))) {
|
||||
GlobalValue *GV = cast<GlobalValue>(CE1->getOperand(0));
|
||||
|
||||
// Functions are at least 4-byte aligned.
|
||||
unsigned GVAlign = GV->getAlignment();
|
||||
if (isa<Function>(GV))
|
||||
GVAlign = std::max(GVAlign, 4U);
|
||||
unsigned GVAlign =
|
||||
GV->getParent()
|
||||
? GV->getPointerAlignment(GV->getParent()->getDataLayout())
|
||||
: 0;
|
||||
|
||||
if (GVAlign > 1) {
|
||||
unsigned DstWidth = CI2->getType()->getBitWidth();
|
||||
|
27
test/Analysis/ConstantFolding/func-and-folding.ll
Normal file
27
test/Analysis/ConstantFolding/func-and-folding.ll
Normal file
@ -0,0 +1,27 @@
|
||||
; RUN: opt < %s -constprop -S -o - | FileCheck %s
|
||||
|
||||
; Function Attrs: minsize norecurse nounwind optsize readnone
|
||||
define dso_local void @foo1() #0 {
|
||||
entry:
|
||||
ret void
|
||||
}
|
||||
|
||||
; Function Attrs: minsize norecurse nounwind optsize readnone
|
||||
define dso_local void @foo2() align 4 {
|
||||
entry:
|
||||
ret void
|
||||
}
|
||||
|
||||
; Function Attrs: minsize nounwind optsize
|
||||
define dso_local i32 @main() local_unnamed_addr #1 {
|
||||
entry:
|
||||
; CHECK: ptrtoint
|
||||
%call = tail call i32 bitcast (i32 (...)* @process to i32 (i32)*)(i32 and (i32 ptrtoint (void ()* @foo1 to i32), i32 2)) #3
|
||||
; CHECK-NEXT: ptrtoint
|
||||
%call2 = tail call i32 bitcast (i32 (...)* @process to i32 (i32)*)(i32 and (i32 ptrtoint (void ()* @foo2 to i32), i32 2)) #3
|
||||
ret i32 0
|
||||
}
|
||||
|
||||
; Function Attrs: minsize optsize
|
||||
declare dso_local i32 @process(...) local_unnamed_addr #2
|
||||
|
@ -1,16 +0,0 @@
|
||||
; RUN: llvm-as < %s | llvm-dis | not grep ptrtoint
|
||||
; RUN: verify-uselistorder %s
|
||||
; All of these should be eliminable
|
||||
|
||||
|
||||
define i32 @foo() {
|
||||
ret i32 and (i32 ptrtoint (i32()* @foo to i32), i32 1)
|
||||
}
|
||||
|
||||
define i32 @foo2() {
|
||||
ret i32 and (i32 1, i32 ptrtoint (i32()* @foo2 to i32))
|
||||
}
|
||||
|
||||
define i1 @foo3() {
|
||||
ret i1 icmp ne (i1()* @foo3, i1()* null)
|
||||
}
|
Loading…
Reference in New Issue
Block a user