llvm / llvm/llvm-project

[hexagon] encoding error w/packetizer

Open
#218,083 2 comments 0 reactions 1 assignee Claimed by @iajbar View on GitHub
backend:Hexagon llvm:codegen miscompilation
Dominant language
LLVM
Stars
40.5k
Forks
18.7k
PR merge metrics
PR metrics pending

Description

When building the linux kernel for hexagon using 22.x clang, we see many mis-encoded instructions. The problem goes away with `-mllvm --disable-packetizer`. We end up with instruction words w/the wrong parse bits.

The reproducer in `repro.c` triggers the same bug with a C file and `clang -O2 -fno-pic`. It does not reproduce with 23.1.0-rc1 -- that version's codegen for the same source is different.

`repro.c`:

```c
struct rcu_state_struct {
long gp_start;
long jiffies_stall;
} rcu_state;

long rcu_state_0;
int rcu_pending_user;

void rcu_pending(void)
{
rcu_pending_user || (*(volatile long *)rcu_state_0);
*(volatile long *)&rcu_state.jiffies_stall;
}

```
Code:
```
# workaround enabled (correct), offset 0x7c4:
7c4: 00 c0 16 75 7516c000 { p0 = cmp.eq(r22,#0x0) } <- parse bits 11

# workaround disabled (buggy), offset 0x70c:
70c: 00 40 16 75 75164000 <- parse bits 01
```

Reduced test case:

```llvm
target datalayout = "e-m:e-p:32:32:32-a:0-n16:32-i64:64:64-i32:32:32-i16:16:16-i1:8:8-f32:32:32-f64:64:64-v32:32:32-v64:64:64-v512:512:512-v1024:1024:1024-v2048:2048:2048"
target triple = "hexagon-unknown-linux-musl"

define void @rcu_pending(ptr %rcu_pending_user, i1 %tobool.not) {
entry:
br i1 %tobool.not, label %lor.rhs, label %lor.end

lor.rhs: ; preds = %entry
%0 = load volatile i32, ptr %rcu_pending_user, align 4
br label %lor.end

lor.end: ; preds = %lor.rhs, %entry
%1 = load volatile i32, ptr null, align 4
ret void
}
```

Failure:
```
$ git checkout release/22.x
$ cd ../obj_llvm
$ ./bin/clang -O2 -fno-pic -c ../packetizer_bug/repro.ll -o out.o

$ llvm-objdump-19 -d out.o

out.o: file format elf32-hexagon

Disassembly of section .text:

00000000 :
0: 00 c0 80 49 4980c000 { r0 = memw(gp+#0x0) }
4: 00 40 00 75 75004000 { p0 = cmp.eq(r0,#0x0)
8: 00 40 00 00 00004000 immext(#0x0)
c: 80 f0 80 9f 9f80f080 if (p0.new) r0 = memw(##0x0) }
10: 00 40 9f 52 529f4000
```

Contributor guide

Open the contributing guide

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.