Index: lib/Target/X86/X86TargetMachine.cpp =================================================================== --- lib/Target/X86/X86TargetMachine.cpp +++ lib/Target/X86/X86TargetMachine.cpp @@ -28,6 +28,10 @@ cl::desc("Enable the machine combiner pass"), cl::init(true), cl::Hidden); +static cl::opt +MalignDouble("malign-double", cl::Hidden, + cl::desc("Align i64 and f64 types to 8 bytes")); + namespace llvm { void initializeWinEHStatePassPass(PassRegistry &); } @@ -71,7 +75,7 @@ Ret += "-p:32:32"; // Some ABIs align 64 bit integers and doubles to 64 bits, others to 32. - if (TT.isArch64Bit() || TT.isOSWindows() || TT.isOSNaCl()) + if (TT.isArch64Bit() || TT.isOSWindows() || TT.isOSNaCl() || MalignDouble) Ret += "-i64:64"; else if (TT.isOSIAMCU()) Ret += "-i64:32-f64:32"; Index: test/CodeGen/X86/llc-malign-double.ll =================================================================== --- /dev/null +++ test/CodeGen/X86/llc-malign-double.ll @@ -0,0 +1,53 @@ +; RUN: llc -mtriple=i386-pc-linux -filetype=asm %s -o - | FileCheck %s +; RUN: llc -mtriple=i386-pc-linux -malign-double -filetype=asm %s -o -| FileCheck %s --check-prefix=MALIGN + +; Test that the -malign-double flag causes i64 and f64 types to have alignment +; 8 instead of 4. + +%structi64 = type { i32, i64 } + +define i32 @check_i64_size() { +; CHECK-LABEL: check_i64_size: + %starti = ptrtoint %structi64* null to i32 + %endp = getelementptr %structi64, %structi64* null, i32 1 + %endi = ptrtoint %structi64* %endp to i32 + %diff = sub i32 %endi, %starti +; CHECK: movl $12, %eax +; MALIGN: movl $16, %eax + ret i32 %diff +} + +define i32 @check_i64_offset() { +; CHECK-LABEL: check_i64_offset: + %starti = ptrtoint %structi64* null to i32 + %endp = getelementptr %structi64, %structi64* null, i32 0, i32 1 + %endi = ptrtoint i64* %endp to i32 + %diff = sub i32 %endi, %starti +; CHECK: movl $4, %eax +; MALIGN: movl $8, %eax + ret i32 %diff +} + +%structf64 = type { i32, double } + +define i32 @check_f64_size() { +; CHECK-LABEL: check_f64_size: + %starti = ptrtoint %structf64* null to i32 + %endp = getelementptr %structf64, %structf64* null, i32 1 + %endi = ptrtoint %structf64* %endp to i32 + %diff = sub i32 %endi, %starti +; CHECK: movl $12, %eax +; MALIGN: movl $16, %eax + ret i32 %diff +} + +define i32 @check_f64_offset() { +; CHECK-LABEL: check_f64_offset: + %starti = ptrtoint %structf64* null to i32 + %endp = getelementptr %structf64, %structf64* null, i32 0, i32 1 + %endi = ptrtoint double* %endp to i32 + %diff = sub i32 %endi, %starti +; CHECK: movl $4, %eax +; MALIGN: movl $8, %eax + ret i32 %diff +}