[prev in list] [next in list] [prev in thread] [next in thread] 

List:       llvm-bugs
Subject:    [LLVMbugs] [Bug 6185] New: llvm-gcc assumes no alignment for
From:       bugzilla-daemon () cs ! uiuc ! edu
Date:       2010-01-31 4:23:40
Message-ID: bug-6185-206 () http ! llvm ! org/bugs/
[Download RAW message or body]

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@nondot.org
        ReportedBy: lessen42@gmail.com
                CC: llvmbugs@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.
_______________________________________________
LLVMbugs mailing list
LLVMbugs@cs.uiuc.edu
http://lists.cs.uiuc.edu/mailman/listinfo/llvmbugs


[prev in list] [next in list] [prev in thread] [next in thread] 

Configure | About | News | Add a list | Sponsored by KoreLogic