<table border="1" cellspacing="0" cellpadding="8">
<tr>
<th>Issue</th>
<td>
<a href=https://github.com/llvm/llvm-project/issues/56295>56295</a>
</td>
</tr>
<tr>
<th>Summary</th>
<td>
[bug] LLVM IR Fixed array values are not returned correctly if larger than 64 bytes when using -O0 on arm64
</td>
</tr>
<tr>
<th>Labels</th>
<td>
</td>
</tr>
<tr>
<th>Assignees</th>
<td>
</td>
</tr>
<tr>
<th>Reporter</th>
<td>
IsaacShelton
</td>
</tr>
</table>
<pre>
### Details
**Description:** When lowering, LLVM IR Fixed array values are not returned correctly if larger than 64 bytes when using -O0 on arm64
**Target:** arm64-apple-darwin21.4.0
**Version:** LLVM 14.0.6 and earlier (until at least LLVM 13.0.1)
### Abstract
Returning a fixed array value doesn't not seem to be correctly lowered when using -O0 on arm64 if the array is larger than 64 bytes.
This issue isn't for any particular language, but I found it using the following code:
```
import 'sys/cstdio.adept'
func getValues() 9 long {
values 9 long
repeat 9 {
values[idx] = idx as long
}
return values
}
func main {
values 9 long = getValues()
repeat 9 {
printf('%c\n', 'A'ub + values[idx] as ubyte)
}
}
```
When the fixed arrays have 8 items (or equivalent 64 bytes), it works correctly. But as soon as you increase it to 9 (or any fixed array with >64 bytes), the LLVM IR is not lowered correctly anymore (at least for -O0 on arm64).
To demonstrate this, here are two LLVM IR files. The only difference between them, is that the size of the fixed arrays and iteration counts are increased from 8 to 9.
Both compile correctly when using `-O1`, but the `error.ll` does not when using `-O0`.
The expected output for both programs looks like this: (but `I` is only for `error.ll` since it shows 9 characters instead of 8):
```
A
B
C
D
E
F
G
H
I
```
However, when compiling `error.ll` with `-O0` you get:
```
A
A
A
A
A
A
A
y
A
```
### Complete LLVM IR
```
ok.ll
```
```
source_filename = ""
target datalayout = "e-m:o-i64:64-i128:128-n32:64-S128"
target triple = "arm64-apple-darwin21.4.0"
@S0 = internal constant [4 x i8] c"%c\0A\00"
declare i32 @printf(i8* %0, ...)
; Function Attrs: nounwind
define private [8 x i64] @a41() #0 {
%1 = alloca [8 x i64], align 8
%2 = alloca i64, align 8
store [8 x i64] zeroinitializer, [8 x i64]* %1, align 8
store i64 0, i64* %2, align 8
br label %13
3: ; preds = %13
%4 = load i64, i64* %2, align 8
%5 = load i64, i64* %2, align 8
%6 = bitcast [8 x i64]* %1 to i64*
%7 = getelementptr i64, i64* %6, i64 %5
store i64 %4, i64* %7, align 8
br label %8
8: ; preds = %3
%9 = load i64, i64* %2, align 8
%10 = add i64 %9, 1
store i64 %10, i64* %2, align 8
br label %13
11: ; preds = %13
%12 = load [8 x i64], [8 x i64]* %1, align 8
ret [8 x i64] %12
13: ; preds = %8, %0
%14 = load i64, i64* %2, align 8
%15 = icmp ult i64 %14, 8
br i1 %15, label %3, label %11
}
; Function Attrs: nounwind
define i32 @main() #0 {
br label %20
1: ; preds = %20
%2 = alloca [8 x i64], align 8
%3 = alloca i64, align 8
%4 = call [8 x i64] @a41()
store [8 x i64] %4, [8 x i64]* %2, align 8
store i64 0, i64* %3, align 8
br label %17
5: ; preds = %17
%6 = load i64, i64* %3, align 8
%7 = bitcast [8 x i64]* %2 to i64*
%8 = getelementptr i64, i64* %7, i64 %6
%9 = load i64, i64* %8, align 8
%10 = trunc i64 %9 to i8
%11 = add i8 65, %10
%12 = call i32 (i8*, ...) @printf(i8* getelementptr inbounds ([4 x i8], [4 x i8]* @S0, i32 0, i32 0), i8 %11)
br label %13
13: ; preds = %5
%14 = load i64, i64* %3, align 8
%15 = add i64 %14, 1
store i64 %15, i64* %3, align 8
br label %17
16: ; preds = %17
ret i32 0
17: ; preds = %13, %1
%18 = load i64, i64* %3, align 8
%19 = icmp ult i64 %18, 8
br i1 %19, label %5, label %16
20: ; preds = %0
br label %1
}
attributes #0 = { nounwind }
```
```
error.ll
```
```
source_filename = ""
target datalayout = "e-m:o-i64:64-i128:128-n32:64-S128"
target triple = "arm64-apple-darwin21.4.0"
@S0 = internal constant [4 x i8] c"%c\0A\00"
declare i32 @printf(i8* %0, ...)
; Function Attrs: nounwind
define private [9 x i64] @a41() #0 {
%1 = alloca [9 x i64], align 8
%2 = alloca i64, align 8
store [9 x i64] zeroinitializer, [9 x i64]* %1, align 8
store i64 0, i64* %2, align 8
br label %13
3: ; preds = %13
%4 = load i64, i64* %2, align 8
%5 = load i64, i64* %2, align 8
%6 = bitcast [9 x i64]* %1 to i64*
%7 = getelementptr i64, i64* %6, i64 %5
store i64 %4, i64* %7, align 8
br label %8
8: ; preds = %3
%9 = load i64, i64* %2, align 8
%10 = add i64 %9, 1
store i64 %10, i64* %2, align 8
br label %13
11: ; preds = %13
%12 = load [9 x i64], [9 x i64]* %1, align 8
ret [9 x i64] %12
13: ; preds = %8, %0
%14 = load i64, i64* %2, align 8
%15 = icmp ult i64 %14, 9
br i1 %15, label %3, label %11
}
; Function Attrs: nounwind
define i32 @main() #0 {
br label %20
1: ; preds = %20
%2 = alloca [9 x i64], align 8
%3 = alloca i64, align 8
%4 = call [9 x i64] @a41()
store [9 x i64] %4, [9 x i64]* %2, align 8
store i64 0, i64* %3, align 8
br label %17
5: ; preds = %17
%6 = load i64, i64* %3, align 8
%7 = bitcast [9 x i64]* %2 to i64*
%8 = getelementptr i64, i64* %7, i64 %6
%9 = load i64, i64* %8, align 8
%10 = trunc i64 %9 to i8
%11 = add i8 65, %10
%12 = call i32 (i8*, ...) @printf(i8* getelementptr inbounds ([4 x i8], [4 x i8]* @S0, i32 0, i32 0), i8 %11)
br label %13
13: ; preds = %5
%14 = load i64, i64* %3, align 8
%15 = add i64 %14, 1
store i64 %15, i64* %3, align 8
br label %17
16: ; preds = %17
ret i32 0
17: ; preds = %13, %1
%18 = load i64, i64* %3, align 8
%19 = icmp ult i64 %18, 9
br i1 %19, label %5, label %16
20: ; preds = %0
br label %1
}
attributes #0 = { nounwind }
```
</pre>
<img width="1px" height="1px" alt="" src="http://email.email.llvm.org/o/eJztWllv2zgQ_jXyC2FDh3U9-CFHsw3QRYG26D4uaIm2uZVELUnFcX_9zlCHJVt24jToAm0CwxIlco6PM99wAi9FultYrld_yC3TlGfKsm8t-6r5dvFzy1Qieam5KCyveUbIXxtWkExsmeTF2nJvyIcPX_8k95_IHX9kKaFS0h15oFnFFAwYKYQmkulKFvA2EVKyRGc7wlcko3LNJNEbWpBgTpY7DUu2KL5SIJtMP9pEFCAkD-Z9u77gOr03yUyY0rLM2DSlcssL15nNZ3Z_zVcm1cAPY7UDs2YBoUVKGJUZB2ssN6oKzTNCNckYVbqZ6cFMx3LjIUwthldLpSVNdP_tJ-M0OkLJ6hAbkgqmCssNtQFIMZYTLciS9SAyIMOyE5AghHrDGqlcjeI561v0ZQOzuFKgnjfKV0KC-ztSUql5UoEIEFOsK7pmuLfLSpN7mFQBQlw3RqDSlcjAPBwlImUIax-XwG4-ZsjzUkgNyIZqpyz3LlE65WJGU1ZqeNhfuaqKhMDmfjXxA3sBiJMYkABFVnhdTyLw1wRY_Wr_eH8nWclgC-Phsv1Sy7_m6aPl3xLLuyVwS6g6FBbejkvGfW3F1Ma3M3te5JQXZ2w2ag88vcyPEhJQr8zK0HL9xPJvCnN7g1BDcIbVEu6ujxwGRysMjqHGzoXuZriL9bfJfhMA-4hWZEMfGIkgQliuMIMgqNi_FQfFrNBdLKI-MA7iaCvkN7WP9Bm5hjgDs5TA4FZkJyrCi0RC_jGcD5kRN3IxWPvZtOV6A1i-O1CCJrbEBEGPOdam0z7BQFYugKJAcpftmBAD4nHjYQ4JkrJcFJjvmoEerlDfBkQbutNb0Sle8QwykHwBW0QB-lK-WsG8ImGQ6HrLaihzA4rCvNXGbsW_w4LVMczUZCEDxUBl4AcQVc2xLVYpWUmRw04gYAOzrwXAlIi8BJN6CPSoBTZ6-tHB7W7yHtXDkEkp5CzL4NaQlsHycB2GyQHVMMIeS9ACRolKl1UN7RLtKKVYS5pjvgmIg4x_a4D0rnAvUDnIu0eNgIuBDtceGAPaExMdaiO2mFbJhiIHA9MDIEozmiKKJrG8cWZqwakvN_WlCf939eWuvvxRX97Xl_szGfIewuyBSUTRoFSD3iDVt7-O3BY9E_NNWTtj6vMvu8Fo1NR9_boBIzOmu5w5w-biG9o_KnQ4VKKSCfsbk6CgOTOEZ7kufsx7bco4SammGQXvdTuDTXNAQUw5ZJ93BaWdO0By3hV8TwvPrZ99xmcHojScVrJO0cljQbuq-Z7bn-26CBQQOwXNYMsgfCgwF3DmnDwSHiFtJsZ4w7OwCr4OJaUsyUw2ei4BqR0_w3IXA9s3qTWbzQ6PEd41uYOSYbL6SmtpEqGA9Aab01b2ihcMOf8BaQcMi9AwQAgr2Nymc6eplrCddr9YgF7HuEehYid0uBQNohlfF5Am-_lufz5OPJ6ltCHOgRnfmRS84JrD3O91BhwoMyg4J8XBNGIwMjrNZHdk8hLPKEuWGWFeH0kPgbvwD9EvoS6oJm46kQaKuXmaCeCSBojztsFj__IlgVmy5DrBEjQKGlJ6Lae3LmxPESxjOZTaUstjnUEzNLYdA45ODheET2Ae9SGPXgPyPuLx5fA5df7SNG09MmcAZ9RZ54cizHEu9_d8hDnu3uGj3Hxu_sCZ9JATUPLA8hckx5HlUX269O2-Ay_IEadOEp7kJaky3e2NWd3fBu7U0_F5tyXeYOQ4o4fwC1i1IWw8sZ8g0X5AuIMa-oJ4OIbV7ePpXsjW3tNs3RFZAtPOFI9z7N7yxFhIju3ySUr3nkq4QUfovwqlh0dkOx6uY7Z1PHuOn91Rfo6ew89hj5-DZxJhdJYItcQGtKVCY9lglrOny4gEfpPTjn3MSiZeTHo0x5j9CWbkiHPgaLHE_xuYhrB_kGqCqDe-IuYQZlwEXf2bumOMmjzfR-gZhn4NnvOfy28nAqbht15FqqntREnyfyRDnOA1SlKXIVhKavD7OsLXKXtNpPWRil6AbjxePaIT1SMe1IthLXGCvp9AxD_upz26Z6NFikJd4tDvMtWUHJQQXndlipz_b8zBw667fOvO_u_uLH55dxa_YncWP9WdxW_d2eXd2TFob93Z79GdxYfd2bPyp-nO4l-iO-sfwd66syfZ-iXd2YnicY7de93ZUUj-dt3ZMQJv3dlbd_bWnZ3X8VO6s5Hq8Ut1Z5N04aWxF9OJ5jpjC0ilZbVGhv4pP5OZVDJbbLQulfmlyx181lxvquUsETkMsuyhvUxLKf4BJTA0PwnBX2b4gRv7k83Cj0MvjFLHD9K546U2C2NvxZgXBCFL08ibGOAUegeuTfjCtV3XhsVwjexgtvITP4nTZRD4gR8t50AgDOp3NkPFMyHXE7kwNgA2Cl5mXGm1f0mVgqBirJVPK70RcnGvKE0-b1imRTExNi-Mwf8BlSlJBw">