[hexagon] hexagon-hwloops pass miscompiles loop (with -fsanitize=undefined)
- Dominant language
- LLVM
- Stars
- 40.5k
- Forks
- 18.7k
- PR merge metrics
- PR metrics pending
Description
Reproducer:
```c
/* Compile with clang --target=hexagon-linux-musl test.c -nostdinc -static -nostdlib -fsanitize=undefined -fsanitize-trap=all -Os */
__attribute__((noinline))
static unsigned long strlen(const char *str)
{
unsigned long len;
for (len = 0; str[len]; len++)
__asm__("");
return len;
}
#define __syscall1(num, arg1) \
({ \
register long _num __asm__ ("r6") = (num); \
register long _arg1 __asm__ ("r0") = (long)(arg1); \
\
__asm__ volatile ( \
"trap0(#1)\n" \
: "+r"(_arg1) \
: "r"(_num) \
: "memory" \
); \
_arg1; \
})
void _start(void)
{
const char *string = "foobar";
int exitcode;
__asm__("" : "+r"(string));
exitcode = strlen(string);
__syscall1(93 /* __NR_exit */, exitcode);
}
```
The reproducer segfaults in the UBSAN trap in `strlen()`, (at 0x101b8)
Any *one* of the following avoids the issue:
* Remove `-fsanitize=undefined`.
* Remove `-Os`.
* Add `-mllvm --disable-hexagon-hwloops`.
The same `strlen()` implementation works fine (with UBSAN) on many other targets.
Object code:
```
00010180 :
10180: 1c 40 00 10 1000401c { p0 = cmp.eq(r0,#0x0); if (p0.new) jump:nt 0x101b8
10184: 00 c0 9d a0 a09dc000 allocframe(#0x0) }
10188: e1 ff 60 76 7660ffe1 { r1 = sub(#-0x1,r0) }
1018c: 21 c0 01 b0 b001c021 { r1 = add(r1,#0x1) }
10190: 00 c0 41 75 7541c000 { p0 = cmp.gt(r1,#0x0) }
10194: 22 40 01 73 73014022 { r2 = mux(p0,r1,#0x1)
10198: 01 c0 00 78 7800c001 r1 = #0x0 }
1019c: 08 c0 02 60 6002c008 { loop0(0x101a0,r2) }
101a0: 02 c0 00 91 9100c002 { r2 = memb(r0+#0x0) }
101a4: 00 40 02 75 75024000 { p0 = cmp.eq(r2,#0x0)
101a8: 00 60 01 74 74016000 if (p0.new) r0 = add(r1,#0x0)
101ac: 1e d8 1e 96 961ed81e if (p0.new) dealloc_return:t }
101b0: 00 80 00 7f 7f008000 { nop
101b4: 00 31 11 31 31113100 r1 = add(r1,#1); r0 = add(r0,#1) } :endloop0
101b8: 3f 70 ad 0b 0bad703f { immext(#0xbadc0fc0)
```
The loop is transformed into a hardware loop, but the loop condition variable is never updated within the loop body.
This is a different semantic than the loop in the C source code.
Clang version: 22.1.8 and current HEAD.
Contributor guide
Assessment
This issue has not been assessed yet.