How about this patch then?
-bw
Index: gcc/llvm-convert.cpp
==================================================================---
gcc/llvm-convert.cpp (revision 43658)
+++ gcc/llvm-convert.cpp (working copy)
@@ -758,7 +758,7 @@
}
-Value *TreeToLLVM::Emit(tree exp, Value *DestLoc) {
+Value *TreeToLLVM::Emit(tree exp, Value *DestLoc, unsigned Alignment) {
assert((isAggregateTreeType(TREE_TYPE(exp)) == (DestLoc != 0) ||
TREE_CODE(exp) == MODIFY_EXPR) &&
"Didn't pass DestLoc to an aggregate expr, or passed it to
scalar!");
@@ -811,7 +811,7 @@
case STRING_CST:
case REALPART_EXPR:
case IMAGPART_EXPR:
- Result = EmitLoadOfLValue(exp, DestLoc);
+ Result = EmitLoadOfLValue(exp, DestLoc, Alignment);
break;
case OBJ_TYPE_REF: Result = EmitOBJ_TYPE_REF(exp); break;
case ADDR_EXPR: Result = EmitADDR_EXPR(exp); break;
@@ -2524,7 +2524,8 @@
/// EmitLoadOfLValue - When an l-value expression is used in a
context that
/// requires an r-value, this method emits the lvalue computation,
then loads
/// the result.
-Value *TreeToLLVM::EmitLoadOfLValue(tree exp, Value *DestLoc) {
+Value *TreeToLLVM::EmitLoadOfLValue(tree exp, Value *DestLoc,
+ unsigned SrcAlign) {
// If this is an SSA value, don't emit a load, just use the result.
if (isGCC_SSA_Temporary(exp)) {
assert(DECL_LLVM_SET_P(exp) && "Definition not found before
use!");
@@ -2540,7 +2541,7 @@
LValue LV = EmitLV(exp);
bool isVolatile = TREE_THIS_VOLATILE(exp);
const Type *Ty = ConvertType(TREE_TYPE(exp));
- unsigned Alignment = expr_align(exp) / 8;
+ unsigned DstAlign = expr_align(exp) / 8;
if (!LV.isBitfield()) {
if (!DestLoc) {
@@ -2548,17 +2549,17 @@
Value *Ptr = CastToType(Instruction::BitCast, LV.Ptr,
PointerType::get(Ty));
LoadInst *LI = Builder.CreateLoad(Ptr, isVolatile, "tmp");
- LI->setAlignment(Alignment);
+ LI->setAlignment(DstAlign);
return LI;
} else {
EmitAggregateCopy(DestLoc, LV.Ptr, TREE_TYPE(exp), false,
isVolatile,
- Alignment);
+ std::min(DstAlign, SrcAlign));
return 0;
}
} else {
// This is a bitfield reference.
LoadInst *LI = Builder.CreateLoad(LV.Ptr, isVolatile, "tmp");
- LI->setAlignment(Alignment);
+ LI->setAlignment(DstAlign);
Value *Val = LI;
unsigned ValSizeInBits = Val->getType()->getPrimitiveSizeInBits();
@@ -3021,7 +3022,7 @@
EmitAggregateCopy(DestLoc, LV.Ptr, TREE_TYPE(exp),
isVolatile, false,
Alignment);
} else if (!isVolatile && TREE_CODE(TREE_OPERAND(exp, 0)) !=
RESULT_DECL) {
- Emit(TREE_OPERAND(exp, 1), LV.Ptr);
+ Emit(TREE_OPERAND(exp, 1), LV.Ptr, Alignment);
} else {
// Need to do a volatile store into TREE_OPERAND(exp, 1). To
do this, we
// emit it into a temporary memory location, then do a
volatile copy into
Index: gcc/llvm-internal.h
==================================================================---
gcc/llvm-internal.h (revision 43658)
+++ gcc/llvm-internal.h (working copy)
@@ -375,7 +375,7 @@
/// expression that fits into an LLVM scalar value, the result is
returned. If
/// the result is an aggregate, it is stored into the location
specified by
/// DestLoc.
- Value *Emit(tree_node *exp, Value *DestLoc);
+ Value *Emit(tree_node *exp, Value *DestLoc, unsigned Alignment = 0);
/// EmitLV - Convert the specified l-value tree node to LLVM
code, returning
/// the address of the result.
@@ -512,7 +512,7 @@
// Expressions.
void EmitINTEGER_CST_Aggregate(tree_node *exp, Value *DestLoc);
- Value *EmitLoadOfLValue(tree_node *exp, Value *DestLoc);
+ Value *EmitLoadOfLValue(tree_node *exp, Value *DestLoc, unsigned
SrcAlign);
Value *EmitOBJ_TYPE_REF(tree_node *exp, Value *DestLoc);
Value *EmitADDR_EXPR(tree_node *exp);
Value *EmitOBJ_TYPE_REF(tree_node *exp);
spang:llvm-9999-01 admin$ cd ..
spang:Clean admin$ ls *.c
t.c testcase.c
spang:Clean admin$ cat > a.c
struct A
{
int a[11];
};
void Qux() {
static struct A C = {0};
struct A __attribute__ ((aligned (1))) Bar;
Bar = C;
}