mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2025-01-19 04:32:19 +00:00
When inferring the pointer alignment, if the global doesn't have an initializer
and the alignment is 0 (i.e., it's defined globally in one file and declared in another file) it could get an alignment which is larger than the ABI allows for that type, resulting in aligned moves being used for unaligned loads. For instance, in file A.c: struct S s; In file B.c: struct { // something long }; extern S s; void foo() { struct S p = s; // ... } this copy is a 'memcpy' which is turned into a series of 'movaps' instructions on X86. But this is wrong, because 'struct S' has alignment of 4, not 16. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@140902 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
parent
8de34006cf
commit
e09b2a0d49
@ -6537,6 +6537,8 @@ unsigned SelectionDAG::InferPtrAlignment(SDValue Ptr) const {
|
||||
Align = TD->getPreferredAlignment(GVar);
|
||||
}
|
||||
}
|
||||
if (!Align)
|
||||
Align = TLI.getTargetData()->getABITypeAlignment(GV->getType());
|
||||
}
|
||||
return MinAlign(Align, GVOffset);
|
||||
}
|
||||
|
26
test/CodeGen/X86/alignment-2.ll
Normal file
26
test/CodeGen/X86/alignment-2.ll
Normal file
@ -0,0 +1,26 @@
|
||||
; RUN: llc < %s -mtriple i386-apple-darwin10 | not grep movaps
|
||||
; <rdar://problem/10058036>
|
||||
|
||||
%struct._psqlSettings = type { %struct.pg_conn*, i32, %struct.__sFILE*, i8, %struct.printQueryOpt, i8*, i8, i32, %struct.__sFILE*, i8, i32, i8*, i8*, i8*, i64, i8, %struct.__sFILE*, %struct._variable*, i8, i8, i8, i8, i8, i32, i32, i32, i32, i32, i8*, i8*, i8*, i32 }
|
||||
%struct.pg_conn = type opaque
|
||||
%struct.__sFILE = type { i8*, i32, i32, i16, i16, %struct.__sbuf, i32, i8*, i32 (i8*)*, i32 (i8*, i8*, i32)*, i64 (i8*, i64, i32)*, i32 (i8*, i8*, i32)*, %struct.__sbuf, %struct.__sFILEX*, i32, [3 x i8], [1 x i8], %struct.__sbuf, i32, i64 }
|
||||
%struct.__sbuf = type { i8*, i32 }
|
||||
%struct.__sFILEX = type opaque
|
||||
%struct.printQueryOpt = type { %struct.printTableOpt, i8*, i8, i8*, i8**, i8, i8, i8* }
|
||||
%struct.printTableOpt = type { i32, i8, i16, i16, i8, i8, i8, i32, %struct.printTextFormat*, i8*, i8*, i8, i8*, i32, i32, i32 }
|
||||
%struct.printTextFormat = type { i8*, [4 x %struct.printTextLineFormat], i8*, i8*, i8*, i8*, i8*, i8*, i8*, i8*, i8*, i8 }
|
||||
%struct.printTextLineFormat = type { i8*, i8*, i8*, i8* }
|
||||
%struct._variable = type { i8*, i8*, void (i8*)*, %struct._variable* }
|
||||
%struct.pg_result = type opaque
|
||||
|
||||
@pset = external global %struct._psqlSettings
|
||||
|
||||
define signext i8 @do_lo_list() nounwind optsize ssp {
|
||||
bb:
|
||||
%myopt = alloca %struct.printQueryOpt, align 4
|
||||
%tmp = bitcast %struct.printQueryOpt* %myopt to i8*
|
||||
call void @llvm.memcpy.p0i8.p0i8.i32(i8* %tmp, i8* bitcast (%struct.printQueryOpt* getelementptr inbounds (%struct._psqlSettings* @pset, i32 0, i32 4) to i8*), i32 76, i32 4, i1 false)
|
||||
ret i8 0
|
||||
}
|
||||
|
||||
declare void @llvm.memcpy.p0i8.p0i8.i32(i8* nocapture, i8* nocapture, i32, i32, i1) nounwind
|
Loading…
x
Reference in New Issue
Block a user