Skip to content

Miscompilation with -fsanitize=undefined,memtag-stack #64309

@ostannard

Description

@ostannard

When this code is compiled with UBSan and MTE stack tagging, the generated code hits a breakpoint instruction to report a UBSan failure, despite the lack of UB in the source code:

int g_12[2] = {0, 0};
int g_21 = 0;

void main() {
  g_12[1];

  int *l_73[3][7] = {{&g_21, &g_21, &g_21, &g_21, &g_21, &g_21},
                     {&g_21, &g_21, &g_21, &g_21, &g_21, &g_21},
                     {&g_21, &g_21, &g_21, &g_21, &g_21, &g_21}};
  l_73[0][2];

  for (int i = 0; i < 2; i++) {
    int **l_76[2][2];
    l_76[1][0] = &g_21;
    l_76[1][0];
  }
}

Generated code:

$ /work/llvm/build/bin/clang --target=aarch64-arm-none-eabi -march=armv8.5-a+memtag -c test.c -o file001051.o -O3 -fsanitize=memtag-stack,undefined -fsanitize-trap=undefined -o - -S
...
main:                                   // @main
        .cfi_startproc
// %bb.0:                               // %entry
        .cfi_mte_tagged_frame
        sub     sp, sp, #208
        .cfi_def_cfa_offset 208
        .cfi_remember_state
        irg     x8, sp
        adrp    x11, g_12
        add     x11, x11, :lo12:g_12
        addg    x9, x8, #32, #1
        mov     x10, x9
        cmn     x11, #4
        mov     x11, #160                       // =0xa0
        stg     x10, [x10], #16
.LBB0_1:                                // %entry
                                        // =>This Inner Loop Header: Depth=1
        sub     x11, x11, #32
        st2g    x10, [x10], #32
        cbnz    x11, .LBB0_1
// %bb.2:                               // %entry
        st2g    x8, [x8]
        b.eq    .LBB0_10
// %bb.3:                               // %cont4
        adrp    x10, .L__const.main.l_73
        add     x10, x10, :lo12:.L__const.main.l_73
        cmn     x9, #17
        ldp     q0, q1, [x10, #128]
        ldp     q2, q3, [x10, #64]
        stp     q0, q1, [sp, #160]
        ldp     q1, q0, [x10, #96]
        stp     q2, q3, [sp, #96]
        ldp     q2, q3, [x10]
        stp     q1, q0, [sp, #128]
        ldp     q1, q0, [x10, #32]
        stp     q2, q3, [sp, #32]
        ldr     x11, [x10, #160]
        stp     q1, q0, [sp, #64]
        str     x11, [sp, #192]
        b.hi    .LBB0_10
// %bb.4:                               // %cont10
        cmn     x8, #17
        //APP
        //NO_APP
        b.hi    .LBB0_10
// %bb.5:                               // %cont10.split
        cmn     x8, #16
        b.eq    .LBB0_9
// %bb.6:                               // %for.body.preheader
        mov     x9, sp
        mov     w0, wzr
        mov     x8, #192                        // =0xc0
        stg     x9, [x9], #16
.LBB0_7:                                // %for.body.preheader
                                        // =>This Inner Loop Header: Depth=1
        sub     x8, x8, #32
        st2g    x9, [x9], #32
        cbnz    x8, .LBB0_7
// %bb.8:                               // %for.body.preheader
        add     sp, sp, #208
        .cfi_def_cfa_offset 0
        ret
.LBB0_9:                                // %for.body.us31
        .cfi_restore_state
        adrp    x8, g_21
        add     x8, x8, :lo12:g_21
        str     x8, [sp, #16]
.LBB0_10:                               // %trap1
        brk     #0x5513
.Lfunc_end0:
...

The breakpoint is hit because the first branch to LBB0_10 is taken. It looks like this is trying to check that the address of g_12[1] is not null, but an MTE tag setting loop has been inserted between the check and the branch, clobbering CPSR.

This is a regression caused by:
#61830
https://reviews.llvm.org/D148508

Metadata

Metadata

Assignees

Type

No type

Projects

Status

Done

Relationships

None yet

Development

No branches or pull requests

Issue actions