Issue 175323
Summary AArch64 machine instruction scheduler miscompiliation
Labels new issue
Assignees
Reporter Noratrieb
    From https://github.com/rust-lang/rust/issues/150898

Compiling the following IR

https://godbolt.org/z/3P7eMP3xEa96ad4a2ab83e748 

<details><summary>Details</summary>
<p>

```llvmir
; ModuleID = 'out.bc'
source_filename = "r92_mem_corruption.e23bb8bd875216ed-cgu.1"
target datalayout = "e-m:o-p270:32:32-p271:32:32-p272:64:64-i64:64-i128:128-n32:64-S128-Fn32"
target triple = "arm64-apple-macosx11.0.0"

; Function Attrs: uwtable
define hidden void @_RNvMs3_NtCsiUiV58Yj4O6_5alloc3vecINtB5_3VecINtNtCsFmdf7n6dk2_4core6option6OptionTINtNtNtBK_3num7nonzero7NonZeromEyyEEE11extend_withCsjqexlxW1I4b_18r92_mem_corruption(ptr noalias noundef align 8 dereferenceable(24) %0, i64 noundef %1, ptr dead_on_return noalias noundef readonly align 8 captures(none) dereferenceable(24) %2) unnamed_addr #0 {
  %4 = getelementptr inbounds nuw i8, ptr %0, i64 16
  %5 = load i64, ptr %4, align 8
  %6 = load i64, ptr %0, align 8
  %7 = sub i64 %6, %5
  %8 = icmp ugt i64 %1, %7
  br i1 %8, label %9, label %11

9:                                                ; preds = %3
  tail call void @_RINvNvMs2_NtCsiUiV58Yj4O6_5alloc7raw_vecINtB8_11RawVecInnerpE7reserve21do_reserve_and_handleNtNtBa_5alloc6GlobalECsjqexlxW1I4b_18r92_mem_corruption(ptr noalias noundef nonnull align 8 dereferenceable(24) %0, i64 noundef %5, i64 noundef %1, i64 noundef 8, i64 noundef 24)
  %10 = load i64, ptr %4, align 8
  br label %11

11:                                               ; preds = %9, %3
  %12 = phi i64 [ %5, %3 ], [ %10, %9 ]
  %13 = getelementptr inbounds nuw i8, ptr %0, i64 8
  %14 = load ptr, ptr %13, align 8
  %15 = icmp ult i64 %12, 384307168202282326
  tail call void @llvm.assume(i1 %15)
  %16 = getelementptr inbounds nuw { [2 x i32], i32, [3 x i32] }, ptr %14, i64 %12
  %17 = icmp ugt i64 %1, 1
  br i1 %17, label %18, label %28

18:                                               ; preds = %11
  %19 = getelementptr inbounds nuw i8, ptr %2, i64 8
  %20 = load i32, ptr %19, align 8
  %21 = icmp eq i32 %20, 0
  %22 = load i64, ptr %2, align 8
  %23 = getelementptr inbounds nuw i8, ptr %2, i64 16
  %24 = load i64, ptr %23, align 8
  br label %36

25:                                               ; preds = %36
  %.lcssa = phi ptr [ %46, %36 ]
  %26 = add i64 %1, -1
  %27 = add i64 %26, %12
  br label %30

28:                                               ; preds = %11
  %29 = icmp eq i64 %1, 0
  br i1 %29, label %34, label %30

30:                                               ; preds = %28, %25
  %31 = phi ptr [ %.lcssa, %25 ], [ %16, %28 ]
  %32 = phi i64 [ %27, %25 ], [ %12, %28 ]
  tail call void @llvm.memcpy.p0.p0.i64(ptr noundef nonnull align 8 dereferenceable(24) %31, ptr noundef nonnull align 8 dereferenceable(24) %2, i64 24, i1 false)
  %33 = add i64 %32, 1
  br label %34

34:                                               ; preds = %30, %28
  %35 = phi i64 [ %33, %30 ], [ %12, %28 ]
  store i64 %35, ptr %4, align 8
  ret void

36:                                               ; preds = %36, %18
  %37 = phi ptr [ %16, %18 ], [ %46, %36 ]
  %38 = phi i64 [ 1, %18 ], [ %43, %36 ]
  %39 = phi i64 [ undef, %18 ], [ %42, %36 ]
  %40 = phi i64 [ undef, %18 ], [ %41, %36 ]
  %41 = select i1 %21, i64 %40, i64 %22
  %42 = select i1 %21, i64 %39, i64 %24
  %43 = add nuw i64 %38, 1
  store i64 %41, ptr %37, align 8
  %44 = getelementptr inbounds nuw i8, ptr %37, i64 8
  store i32 %20, ptr %44, align 8
  %45 = getelementptr inbounds nuw i8, ptr %37, i64 16
  store i64 %42, ptr %45, align 8
  %46 = getelementptr inbounds nuw i8, ptr %37, i64 24
  %47 = icmp eq i64 %43, %1
  br i1 %47, label %25, label %36
}

; Function Attrs: nocallback nofree nosync nounwind willreturn memory(inaccessiblemem: write)
declare void @llvm.assume(i1 noundef) #1

; Function Attrs: nocallback nofree nounwind willreturn memory(argmem: readwrite)
declare void @llvm.memcpy.p0.p0.i64(ptr noalias writeonly captures(none), ptr noalias readonly captures(none), i64, i1 immarg) #2

; Function Attrs: cold uwtable
declare hidden void @_RINvNvMs2_NtCsiUiV58Yj4O6_5alloc7raw_vecINtB8_11RawVecInnerpE7reserve21do_reserve_and_handleNtNtBa_5alloc6GlobalECsjqexlxW1I4b_18r92_mem_corruption(ptr noalias noundef align 8 dereferenceable(16), i64 noundef, i64 noundef, i64 noundef range(i64 1, -9223372036854775807), i64 noundef) unnamed_addr #3

attributes #0 = { uwtable "frame-pointer"="non-leaf" "probe-stack"="inline-asm" "target-cpu"="apple-m1" }
attributes #1 = { nocallback nofree nosync nounwind willreturn memory(inaccessiblemem: write) }
attributes #2 = { nocallback nofree nounwind willreturn memory(argmem: readwrite) }
attributes #3 = { cold uwtable "frame-pointer"="non-leaf" "probe-stack"="inline-asm" "target-cpu"="apple-m1" }

!llvm.module.flags = !{!0, !1}

!0 = !{i32 8, !"PIC Level", i32 2}
!1 = !{i32 7, !"PIE Level", i32 2}
```

</p>
</details>

results in a miscompilation in the AArch64 backend Machine Instruction scheduler pass (discovered via opt-bisect-limit).

The miscompilation originally manifested via a crash in the MacOS allocator (this code is from Rusts vector type) where it seems like something was mishandled to caused the vector to have invalid pointers that were then freed. Reproducing the bug from the minimized IR is really hard and required a very hacky setup, so I hope it's evident enough by just looking at the code and seeing the transforms 😅
_______________________________________________
llvm-bugs mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-bugs

Reply via email to