llvm / llvm/llvm-project

[AArch64] STRXui: Bad machine code: Using an undefined physical register

Open
#178,146 8 comments 0 reactions 0 assignees View on GitHub
backend:AArch64 crash-on-valid generated by fuzzer
Dominant language
LLVM
Stars
40.5k
Forks
18.7k
PR merge metrics
PR metrics pending

Description

llvm-reduce wasn't able to reduce this further, so am copying the IR reproducer below here for completeness but it is rather large:

```llvm
target datalayout = "e-m:e-p270:32:32-p271:32:32-p272:64:64-i8:8:32-i16:16:32-i64:64-i128:128-n32:64-S128-Fn32"
target triple = "aarch64-unknown-linux-gnu"

@c = external global i32

define i1 @_Z1jiibibcbPcPiPA5_A5_jPA5_A5_sS6_PbPA5_A5_l(i32 %i, i32 %n, i1 %o, ptr %t, ptr %p, ptr %q, ptr %ad, ptr %ae, i16 %conv19, i64 %conv27.us, i16 %conv29, i64 %idxprom79, ptr %arrayidx96, ptr %0, i64 %1, i64 %aq.0212.us.us248.us, %2, ptr %arrayidx118.us.us.us, %broadcast.splatinsert793, %3, %predphi, i64 %index805, i64 %4, i64 %5, i1 %cmp13) #0 {
entry:
%6 = sext i32 0 to i64
br label %for.cond4.preheader

for.cond4.preheader: ; preds = %middle.block827, %entry
br i1 %cmp13, label %for.body18.us, label %for.body45.lr.ph

for.body18.us: ; preds = %for.cond20.for.cond.cleanup22_crit_edge.us, %for.cond4.preheader
%an.0202.us = phi i32 [ %add33.us, %for.cond20.for.cond.cleanup22_crit_edge.us ], [ %i, %for.cond4.preheader ]
br label %for.body23.us

for.body23.us: ; preds = %for.body23.us, %for.body18.us
%ao.0201.us = phi i16 [ %conv19, %for.body18.us ], [ 0, %for.body23.us ]
store i64 %conv27.us, ptr %t, align 8
%add.us = or i16 %ao.0201.us, %conv29
%tobool21.not.us = icmp eq i16 %add.us, 0
br i1 %tobool21.not.us, label %for.cond20.for.cond.cleanup22_crit_edge.us, label %for.body23.us

for.cond20.for.cond.cleanup22_crit_edge.us: ; preds = %for.body23.us
%add33.us = or i32 %an.0202.us, %n
%tobool.not.us = icmp eq i32 %an.0202.us, 0
br label %for.body18.us

for.body45.lr.ph: ; preds = %for.cond4.preheader
%arrayidx98 = getelementptr i32, ptr %arrayidx96, i64 %idxprom79
br i1 %o, label %for.cond51.preheader.us.us247.us, label %for.cond51.preheader.us.us247

for.cond51.preheader.us.us247.us: ; preds = %middle.block827, %for.body45.lr.ph
%aq.0212.us.us248.us13 = phi i64 [ %add129.us.us250.us, %middle.block827 ], [ 0, %for.body45.lr.ph ]
%invariant.gep.us.us249.us14 = getelementptr [5 x i32], ptr %q, i64 %aq.0212.us.us248.us13
%7 = load i32, ptr %arrayidx98, align 4
%8 = load i16, ptr null, align 2
%9 = icmp ne i16 %8, 0
%10 = trunc i32 %7 to i16
%broadcast.splat790 = shufflevector %2, zeroinitializer, zeroinitializer
%broadcast.splat794 = shufflevector %broadcast.splatinsert793, zeroinitializer, zeroinitializer
%.scalar1325 = tail call i16 @llvm.umin.i16(i16 1, i16 %10)
%wide.masked.gather819 = tail call @llvm.masked.gather.nxv16i64.nxv16p0( %broadcast.splat794, %broadcast.splat790, zeroinitializer)
br label %vector.body804

vector.body804: ; preds = %vector.body804, %for.cond51.preheader.us.us247.us
%vec.ind806 = phi [ %3, %for.cond51.preheader.us.us247.us ], [ zeroinitializer, %vector.body804 ]
%11 = zext zeroinitializer to
%predphi20 = select i1 %9, %11, zeroinitializer
%12 = extractelement %predphi, i32 %i
%13 = getelementptr i8, ptr %0, zeroinitializer
%wide.masked.gather812 = tail call @llvm.masked.gather.nxv16i8.nxv16p0( %13, %2, zeroinitializer)
%14 = extractelement %wide.masked.gather812, i32 1
%15 = icmp eq i8 %14, 0
%16 = zext i1 %15 to i64
tail call void @llvm.masked.scatter.nxv16i64.nxv16p0( splat (i64 -7704966459786987552), zeroinitializer, %2)
tail call void @llvm.masked.scatter.nxv16i64.nxv16p0( zeroinitializer, zeroinitializer, %2)
tail call void @llvm.masked.scatter.nxv16i64.nxv16p0( zeroinitializer, zeroinitializer, %2)
tail call void @llvm.masked.scatter.nxv16i64.nxv16p0( %wide.masked.gather819, zeroinitializer, %2)
%17 = getelementptr i8, ptr %ae, %vec.ind806
%wide.masked.gather821 = tail call @llvm.masked.gather.nxv16i8.nxv16p0( %17, splat (i1 true), zeroinitializer)
%wide.masked.gather822 = tail call @llvm.masked.gather.nxv16i8.nxv16p0( zeroinitializer, %broadcast.splat790, zeroinitializer)
%18 = zext %wide.masked.gather821 to
%19 = zext %wide.masked.gather822 to
tail call void @llvm.masked.scatter.nxv16i32.nxv16p0( %18, shufflevector ( insertelement ( poison, ptr @c, i64 0), poison, zeroinitializer), %broadcast.splat790)
tail call void @llvm.masked.scatter.nxv16i32.nxv16p0( %19, zeroinitializer, splat (i1 true))
%index.next825 = add i64 %index805, %4
%20 = icmp eq i64 %index.next825, 0
br i1 %20, label %middle.block827, label %vector.body804

middle.block827: ; preds = %vector.body804
store i64 %12, ptr %p, align 8
store i64 %16, ptr %t, align 8
store i16 %.scalar1325, ptr %t, align 2
%add129.us.us250.us = or i64 %aq.0212.us.us248.us13, 1
br i1 %o, label %for.cond4.preheader, label %for.cond51.preheader.us.us247.us

for.cond51.preheader.us.us247: ; preds = %cond.end.us.us, %for.body45.lr.ph
br label %for.body55.us213.us

for.body55.us213.us: ; preds = %cond.end.us.us, %for.cond51.preheader.us.us247
%indvars.iv34522 = phi i64 [ %aq.0212.us.us248.us, %cond.end.us.us ], [ %6, %for.cond51.preheader.us.us247 ]
br i1 %o, label %cond.end.us.us, label %cond.true.us.us

cond.true.us.us: ; preds = %for.body55.us213.us
%21 = load i32, ptr null, align 4
br label %cond.end.us.us

cond.end.us.us: ; preds = %cond.true.us.us, %for.body55.us213.us
store i64 0, ptr %arrayidx118.us.us.us, align 8
%22 = load i32, ptr %arrayidx98, align 4
%conv99.us.us = trunc i32 %22 to i16
%.sroa.speculated189.us.us = tail call i16 @llvm.umin.i16(i16 1, i16 %conv99.us.us)
store i16 %.sroa.speculated189.us.us, ptr %q, align 2
store i64 0, ptr %ad, align 8
store i64 %5, ptr %p, align 8
%indvars.iv.next346 = or i64 %indvars.iv34522, %1
%cmp53.us224.us = icmp slt i64 %indvars.iv.next346, %idxprom79
br i1 %cmp53.us224.us, label %for.body55.us213.us, label %for.cond51.preheader.us.us247
}

; Function Attrs: nocallback nocreateundeforpoison nofree nosync nounwind speculatable willreturn memory(none)
declare i16 @llvm.umin.i16(i16, i16) #1

; Function Attrs: nocallback nofree nosync nounwind willreturn memory(read)
declare @llvm.masked.gather.nxv16i8.nxv16p0(, , ) #2

; Function Attrs: nocallback nofree nosync nounwind willreturn memory(write)
declare void @llvm.masked.scatter.nxv16i64.nxv16p0(, , ) #3

; Function Attrs: nocallback nofree nosync nounwind willreturn memory(read)
declare @llvm.masked.gather.nxv16i64.nxv16p0(, , ) #2

; Function Attrs: nocallback nofree nosync nounwind willreturn memory(write)
declare void @llvm.masked.scatter.nxv16i32.nxv16p0(, , ) #3

; uselistorder directives
uselistorder ptr @llvm.umin.i16, { 1, 0 }
uselistorder ptr @llvm.masked.gather.nxv16i8.nxv16p0, { 2, 1, 0 }
uselistorder ptr @llvm.masked.scatter.nxv16i64.nxv16p0, { 3, 2, 1, 0 }
uselistorder ptr @llvm.masked.scatter.nxv16i32.nxv16p0, { 1, 0 }

attributes #0 = { "target-cpu"="grace" }
attributes #1 = { nocallback nocreateundeforpoison nofree nosync nounwind speculatable willreturn memory(none) }
attributes #2 = { nocallback nofree nosync nounwind willreturn memory(read) }
attributes #3 = { nocallback nofree nosync nounwind willreturn memory(write) }

```

Compiled with `llc -verify-machineinstrs`, this runs into the following verifier error:

```
*** Bad machine code: Using an undefined physical register ***
- function: _Z1jiibibcbPcPiPA5_A5_jPA5_A5_sS6_PbPA5_A5_l
- basic block: %bb.12 select.end (0x112eaf50)
- instruction: STRXui killed $x8, $sp, 0 :: (store (s64) into %stack.29)
- operand 0: killed $x8
LLVM ERROR: Found 1 machine code errors.
```

See also: https://godbolt.org/z/GvcYsGsr4

The reduced fuzzer test-case:

```c++
#include
long a, b;
unsigned short d;
int c, f, g;
extern long h[][1][1];
extern long e[][1];
char *ac;
void j(signed i, int n, bool o, int k, bool l, char m, bool s, char t[],
signed p[], unsigned q[][5][5], short r[][5][5], short ad[][5][5],
bool ae[], long af[][5][5]) {
for (int ag;; ag = 1)
for (short al = 0; al < 5; al = f)
for (char u; u < (char)n; u = l) {
for (short am; am < i;)
for (int an(i); an; an += k)
for (short ao(s); ao; ao += o)
a = std::max(short(t[ag]), (short)m);
for (bool ap(g); ap < (bool)m; ap = l)
for (long aq(i); aq; aq += 4)
#pragma clang loop vectorize(enable)
for (int ar(k); ar < m; ar += g + 10) {
h[u][u][u] =
ad[ap][ap][ap] ? std::max(q[ar][aq][ag], q[ag][ag][ag]) : 0;
a = !ac[ar];
if (std::max(n, 0)) {
d = std::min(d, (unsigned short)q[ag][u][u]);
if (r[aq][aq][1]) {
e[u][u] =
std::max(10741777613922564064, (unsigned long long)p[u]);
b = af[1][1][aq];
c = 3 ? -ae[ar] : 0;
}
}
}
}
}
```

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.