[LLVMbugs] [Bug 6185] New: llvm-gcc assumes no alignment for bitfield loads

bugzilla-daemon at cs.uiuc.edu bugzilla-daemon at cs.uiuc.edu
Sat Jan 30 20:23:40 PST 2010


http://llvm.org/bugs/show_bug.cgi?id=6185

           Summary: llvm-gcc assumes no alignment for bitfield loads
           Product: tools
           Version: trunk
          Platform: Macintosh
        OS/Version: MacOS X
            Status: NEW
          Severity: normal
          Priority: P2
         Component: llvm-gcc
        AssignedTo: unassignedbugs at nondot.org
        ReportedBy: lessen42 at gmail.com
                CC: llvmbugs at cs.uiuc.edu


Consider the following C code:

struct bf1_31 {
    unsigned a:1;
    unsigned b:31;
};

void func(struct bf1_31 *p, int n, int a)
{
    int i = 0;
    do {
        if (p[i].a)
            p[i].b += a;
    } while (++i < n);
}

llvm-gcc emits the following llvm ir for 32-bit targets:

; ModuleID = 'bitfield.c'
target datalayout =
"e-p:32:32:32-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-n32"
target triple = "armv5e-none-linux-gnueabi"

%struct.bf1_31 = type <{ i32 }>

define arm_aapcscc void @func(%struct.bf1_31* nocapture %p, i32 %n, i32 %a)
nounwind {
entry:
  %0 = shl i32 %a, 1                              ; <i32> [#uses=1]
  %tmp4 = icmp sgt i32 %n, 1                      ; <i1> [#uses=1]
  %smax = select i1 %tmp4, i32 %n, i32 1          ; <i32> [#uses=1]
  br label %bb

bb:                                               ; preds = %bb2, %entry
  %i.0 = phi i32 [ 0, %entry ], [ %4, %bb2 ]      ; <i32> [#uses=2]
  %scevgep5 = getelementptr inbounds %struct.bf1_31* %p, i32 %i.0, i32 0 ;
<i32*> [#uses=2]
  %1 = load i32* %scevgep5, align 1               ; <i32> [#uses=2]
  %tmp = and i32 %1, 1                            ; <i32> [#uses=1]
  %2 = icmp eq i32 %tmp, 0                        ; <i1> [#uses=1]
  br i1 %2, label %bb2, label %bb1

bb1:                                              ; preds = %bb
  %3 = add i32 %1, %0                             ; <i32> [#uses=1]
  store i32 %3, i32* %scevgep5, align 1
  br label %bb2

bb2:                                              ; preds = %bb, %bb1
  %4 = add nsw i32 %i.0, 1                        ; <i32> [#uses=2]
  %exitcond = icmp eq i32 %4, %smax               ; <i1> [#uses=1]
  br i1 %exitcond, label %return, label %bb

return:                                           ; preds = %bb2
  ret void
}

The problem is line
  %1 = load i32* %scevgep5, align 1               ; <i32> [#uses=2]

ARM ABI at least requires that bitfield types be contained within one naturally
aligned instance of its declared type. In this case, this means unsigned int
and 32-bit alignment. I'd be surprised if other ABIs allowed less alignment.

This leads to rather inefficient code on this sample on at least armv5 targets
since they don't support unaligned loads.

clang doesn't specify alignment for this load and generates better code for
armv5.


-- 
Configure bugmail: http://llvm.org/bugs/userprefs.cgi?tab=email
------- You are receiving this mail because: -------
You are on the CC list for the bug.



More information about the llvm-bugs mailing list