Global unaligned member can't be get with pointer

1.I have tried in clang with target arm or mips. and they always use load32 to get unaligned memory.
2.I think it is a bug of llvm, Is there any method to avoid it?
3.I ask similar quetion before.

#pragma pack(push)
#pragma pack(1)
struct S0 {
  char  f4;
  int  f5;

#pragma pack(pop)
struct S0 g_1 = {3,103};
/* ---------------------------------------- */
int main (void){
   //g_1.f5 = g_1.f5 + 1;
	int *x = &(g_1.f5);
	int y = *x;
	*x = 1;
	return 0;

mips asm:

	.option	pic0
	.section	.mdebug.abi32,"",@progbits
	.nan	legacy
	.file	"input.c"
	.globl	main                    # -- Begin function main
	.p2align	2
	.type	main,@function
	.set	nomicromips
	.set	nomips16
	.ent	main
main:                                   # @main
	.frame	$fp,24,$ra
	.mask 	0xc0000000,-4
	.fmask	0x00000000,0
	.set	noreorder
	.set	nomacro
	.set	noat
# %bb.0:                                # %entry
	addiu	$sp, $sp, -24
	sw	$ra, 20($sp)            # 4-byte Folded Spill
	sw	$fp, 16($sp)            # 4-byte Folded Spill
	move	$fp, $sp
	sw	$zero, 12($fp)
	lui	$1, %hi(g_1)
	addiu	$1, $1, %lo(g_1)
	addiu	$1, $1, 1
	sw	$1, 8($fp)
	lw	$1, 8($fp)
	lw	$1, 0($1)
	sw	$1, 4($fp)
	lw	$1, 8($fp)
	addiu	$2, $zero, 1
	sw	$2, 0($1)
	addiu	$2, $zero, 0
	move	$sp, $fp
	lw	$fp, 16($sp)            # 4-byte Folded Reload
	lw	$ra, 20($sp)            # 4-byte Folded Reload
	jr	$ra
	addiu	$sp, $sp, 24
	.set	at
	.set	macro
	.set	reorder
	.end	main
	.size	main, ($func_end0)-main
                                        # -- End function
	.type	g_1,@object             # @g_1
	.globl	g_1
	.byte	3                       # 0x3
	.4byte	103                     # 0x67
	.size	g_1, 5

	.ident	"clang version 10.0.0 (git@ 2471a81b17b3909d7fc21bd8404a4220257c984f)"
	.section	".note.GNU-stack","",@progbits

int32* point to unaligned memory. addr is 4 bytes aligned in stack, but its value is not. So store/load can’t get unaligned info.

And I find this is an old question.

1 Like

It’s a bug with your code, not LLVM.

When you declare a packed struct, only direct field references are guaranteed to generate underaligned load/store instructions. By writing the line int *x = &(g_1.f5);, you are now storing the address in a pointer variable that is assumed to be correctly aligned. Since the member is not in fact correctly aligned, you now have undefined behavior (creating unaligned pointers is UB in C/C++).

Yes, thanks.
I find the UB in c99 std( Pointer)