[llvm-bugs] [Bug 43264] New: [ARM][AACPS] Volatile bitfield does not follow the aacps

via llvm-bugs llvm-bugs at lists.llvm.org
Tue Sep 10 07:25:48 PDT 2019


https://bugs.llvm.org/show_bug.cgi?id=43264

            Bug ID: 43264
           Summary: [ARM][AACPS] Volatile bitfield does not follow the
                    aacps
           Product: clang
           Version: trunk
          Hardware: All
                OS: All
            Status: NEW
          Severity: normal
          Priority: P
         Component: LLVM Codegen
          Assignee: unassignedclangbugs at nondot.org
          Reporter: diogo.sampaio at arm.com
                CC: lebedev.ri at gmail.com, llvm-bugs at lists.llvm.org,
                    neeilans at live.com, richard-llvm at metafoo.co.uk

>From the Procedure Call Standard for the Arm Architecture, Release 2019Q1.1 (
https://static.docs.arm.com/ihi0042/g/aapcs32.pdf?_ga=2.183887654.1224563356.1568044683-65427396.1558599897
) section 8.1 at Volatile bit-fields – preserving number and width of container
accesses:

When a volatile bit-field is read, and its container does not overlap with any
non-bit-field member, its container must be read exactly once using the access
width appropriate to the type of the container.

When a volatile bit-field is written, and its container does not overlap with
any non-bit-field member, its container must be read exactly once and written
exactly once using the access width appropriate to the type of the container.
The two accesses are not atomic.

Note: This ABI does not place any restrictions on the access widths of
bit-fields where the container overlaps with a non-bit-field member. This is
because the C/C++ memory model defines these as being separate memory
locations, which can be accessed by two threads simultaneously. For this
reason, compilers must be permitted to use a narrower memory access width
(including splitting the access into multiple instructions) to avoid writing to
a different memory location. For example, in struct S { int 8 a:24; char b; };
a write to a must not also write to the location occupied by b, this requires
at least
two memory accesses in all current Arm architectures.

-----
Now clang fails in two ways to follow these rules.
e.g.
struct S {
int x : 16;
};

void bla(volatile struct S* S){
                S->x = 1;
}
-----
compiled with
clang -cc1 -internal-isystem
/work/bf/LLVM/monorepo/build/lib/clang/10.0.0/include -nostdsysteminc -triple
armv8-none-linux-eabi -S -o - -O3 -std=c11 test7.c -emit-llvm
--
produces:
--
define void @bla(%struct.S* %S) local_unnamed_addr #0 {
entry:
  %0 = getelementptr inbounds %struct.S, %struct.S* %S, i32 0, i32 0
  store volatile i16 1, i16* %0, align 4
  ret void
}
---
we would expect
define void @bla(%struct.S* %S) local_unnamed_addr #0 {
entry:
  %0 = getelementptr inbounds %struct.S, %struct.S* %S, i32 0, i32 0
  %bf.load = load volatile i32, i32* %0, align 4 ;  <<== a volatile write
requires at least one read. Width = 32bits == sizeof(int), not 16
  store volatile i32 1, i32* %0, align 4 ; Width = 32bits == sizeof(int), not
16
  ret void
}


--------

-- 
You are receiving this mail because:
You are on the CC list for the bug.
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/llvm-bugs/attachments/20190910/4811241b/attachment.html>


More information about the llvm-bugs mailing list