<table border="1" cellspacing="0" cellpadding="8">
<tr>
<th>Issue</th>
<td>
<a href=https://github.com/llvm/llvm-project/issues/55051>55051</a>
</td>
</tr>
<tr>
<th>Summary</th>
<td>
Some `-O0` llvm to riscv backend stack pointer calculation error in for loops
</td>
</tr>
<tr>
<th>Labels</th>
<td>
</td>
</tr>
<tr>
<th>Assignees</th>
<td>
</td>
</tr>
<tr>
<th>Reporter</th>
<td>
victoryang00
</td>
</tr>
</table>
<pre>
I'm transcoding the following llvm code to riscv backend using clang 15.0.0 git hash cac19f414124bf6f2ba78cbe51ed52764e8df237. The command is `clang -mno-relax -no-integrated-as -O0 -w --target=riscv32-unknown-elf`
```llvm
; ModuleID = 'ChocoPy code'
source_filename = "/Users/yiweiyang/project/bak/chocopy_test/pa3/sample/stmt_for_str_same_var.py"
%$union.type = type { i32 }
%$union.len = type { i32 }
%$union.put = type { i32 }
%$union.conslist = type { i32 }
%$object$prototype_type = type {
i32,
i32,
%$object$dispatchTable_type*
}
@$object$prototype = global %$object$prototype_type{
i32 0,
i32 3,
%$object$dispatchTable_type* @$object$dispatchTable
}
%$object$dispatchTable_type = type {
%$object$dispatchTable_type(%$object$dispatchTable_type)*
}
@$object$dispatchTable = global %$object$dispatchTable_type {
%$object$dispatchTable_type(%$object$dispatchTable_type)* @$object.__init__
}
%$int$prototype_type = type {
i32,
i32,
%$int$dispatchTable_type*,
i32
}
@$int$prototype = global %$int$prototype_type{
i32 1,
i32 4,
%$int$dispatchTable_type* @$int$dispatchTable,
i32 0
}
%$int$dispatchTable_type = type {
%$object$dispatchTable_type(%$object$dispatchTable_type)*
}
@$int$dispatchTable = global %$int$dispatchTable_type {
%$object$dispatchTable_type(%$object$dispatchTable_type)* @$object.__init__
}
%$bool$prototype_type = type {
i32,
i32,
%$bool$dispatchTable_type*,
i1
}
@$bool$prototype = global %$bool$prototype_type{
i32 2,
i32 4,
%$bool$dispatchTable_type* @$bool$dispatchTable,
i1 0
}
%$bool$dispatchTable_type = type {
%$object$dispatchTable_type(%$object$dispatchTable_type)*
}
@$bool$dispatchTable = global %$bool$dispatchTable_type {
%$object$dispatchTable_type(%$object$dispatchTable_type)* @$object.__init__
}
%$str$prototype_type = type {
i32,
i32,
%$str$dispatchTable_type*,
i32 ,
i8*
}
@$str$prototype = global %$str$prototype_type{
i32 3,
i32 5,
%$str$dispatchTable_type* @$str$dispatchTable,
i32 0,
i8* inttoptr (i32 0 to i8*)
}
%$str$dispatchTable_type = type {
%$object$dispatchTable_type(%$object$dispatchTable_type)*
}
@$str$dispatchTable = global %$str$dispatchTable_type {
%$object$dispatchTable_type(%$object$dispatchTable_type)* @$object.__init__
}
%$.list$prototype_type = type {
i32,
i32,
%$union.type ,
i32 ,
%$union.conslist*
}
@$.list$prototype = global %$.list$prototype_type{
i32 -1,
i32 5,
%$union.type {i32 0 },
i32 0,
%$union.conslist* inttoptr (i32 0 to %$union.conslist*)
}
@const_0 = external global %$bool$prototype_type
@const_1 = external global %$bool$prototype_type
@const_2 = external global %$str$prototype_type
@const_3 = external global %$str$prototype_type
@const_4 = external global %$str$prototype_type
@const_5 = external global %$str$prototype_type
@const_6 = external global %$str$prototype_type
@const_7 = external global %$str$prototype_type
@const_9 = global %$str$prototype_type {
i32 3,
i32 5,
%$str$dispatchTable_type* @$str$dispatchTable,
i32 3,
i8* getelementptr inbounds ([4 x i8], [4 x i8]* @str.const_9, i32 0, i32 0)
}
@str.const_9 = private unnamed_addr global [4 x i8] c"xXx\10", align 1
declare %$object$dispatchTable_type @$object.__init__(%$object$dispatchTable_type)
declare void @heap.init()
declare %$str$dispatchTable_type* @initchars(i8)
declare %$int$dispatchTable_type* @noconv()
declare void @error.OOB()
declare void @error.None()
declare void @error.Div()
declare %$.list$prototype_type* @concat(%$.list$prototype_type*, %$.list$prototype_type*)
declare %$.list$prototype_type* @conslist(i32, %$union.conslist, ...)
declare i32 @$len(%$union.len)
declare void @print(%$union.put*)
declare %$bool$prototype_type* @makebool(i1)
declare %$int$prototype_type* @makeint(i32)
declare %$str$prototype_type* @makestr(%$str$prototype_type*)
declare %$str$prototype_type* @$input()
declare i1 @streql(%$str$prototype_type*)
declare i1 @strneql(%$str$prototype_type*)
declare %$str$prototype_type* @strcat(%$str$prototype_type*, %$str$prototype_type*)
@llvm.global_ctors = appending global [1 x { i32, void ()*, i8* }] [{ i32, void ()*, i8* } { i32 65535, void ()* @before_main, i8* null }]
define void @before_main() {
label0:
tail call void asm sideeffect "lui a0, 8192\0A add s11, zero, a0", ""()
call void @heap.init()
tail call void asm sideeffect "mv s10, gp\0A add s11, s11, s10\0A mv fp, zero\0A lw ra, 12(sp)\0A addi sp, sp, 16\0A ret", ""()
unreachable
}
define void @main() {
label0:
tail call void asm sideeffect "addi fp, sp, 0", ""()
%op2 = alloca i32
store i32 0, i32* %op2
%op3 = load i32, i32* %op2
%op4 = alloca %$str$prototype_type
%op5 = bitcast %$str$prototype_type* %op4 to %$str$prototype_type**
store %$str$prototype_type* @const_9, %$str$prototype_type** %op5
%op6 = bitcast %$str$prototype_type** %op5 to %$union.len*
%op7 = load %$union.len, %$union.len* %op6
%op8 = call i32 @$len(%$union.len %op7)
%op9 = sub i32 %op8, 1
br label %label10
label10: ; preds = %label0, %label21
%op11 = phi i32 [ %op3, %label0 ], [ %op19, %label21 ]
%op12 = icmp ne i32 %op9, %op11
%op13 = getelementptr %$str$prototype_type, %$str$prototype_type* @const_9, i32 0, i32 4
%op14 = load i8*, i8** %op13
%op15 = bitcast i8* %op14 to i8**
%op16 = getelementptr i8*, i8** %op15, i32 %op11
%op17 = bitcast i8** %op16 to i8*
%op18 = load i8, i8* %op17
%op19 = add i32 %op11, 1
%op20 = call %$str$dispatchTable_type* @initchars(i8 %op18)
br label %label21
label21: ; preds = %label10
%op22 = bitcast %$str$dispatchTable_type* %op20 to %$union.put*
call void @print(%$union.put* %op22)
br i1 %op12, label %label10, label %label23
label23: ; preds = %label21
%op24 = bitcast %$str$dispatchTable_type* %op20 to %$union.put*
call void @print(%$union.put* %op24)
tail call void asm sideeffect "li a7, 93 #exit system call\0Aecall", ""()
ret void
}
```
In function main, the first load to sp + 28 and by the end of loop body reuse sp + 28, so that next load in the epilogue of %label10 is wrong for loop iterable.
```assembly
.globl main
.p2align 1
.type main,@function
main:
.cfi_startproc
addi sp, sp, -64
.cfi_def_cfa_offset 64
sw ra, 60(sp)
.cfi_offset ra, -4
#APP
mv s0, sp
#NO_APP
li a0, 0
sw a0, 56(sp)
sw a0, 20(sp)
lui a0, %hi(const_9)
addi a0, a0, %lo(const_9)
sw a0, 32(sp)
call ($len)@plt
mv a1, a0
lw a0, 20(sp)
addi a1, a1, -1
sw a1, 24(sp)
sw a0, 28(sp)
j .LBB1_1
.LBB1_1:
lw a0, 24(sp)
lw a1, 28(sp) // again load
xor a0, a0, a1
snez a0, a0
sw a0, 8(sp)
lui a0, %hi(const_9)
addi a0, a0, %lo(const_9)
lw a0, 16(a0)
slli a2, a1, 2
add a0, a0, a2
addi a1, a1, 1
sw a1, 12(sp)
lb a0, 0(a0)
call initchars@plt
sw a0, 16(sp)
j .LBB1_2
.LBB1_2:
lw a0, 16(sp)
call print@plt
lw a2, 12(sp)
lw a0, 8(sp)
li a1, 0
sw a2, 28(sp) // overshadow store of sp + 28
bne a0, a1, .LBB1_1
j .LBB1_3
.LBB1_3:
lw a0, 16(sp)
call print@plt
#APP
li a7, 93 #exit system call
ecall
#NO_APP
lw ra, 60(sp)
addi sp, sp, 64
ret
.Lfunc_end1:
.size main, .Lfunc_end1-main
.cfi_endproc
```
However, if I switch to -O1, everything is okay.
```riscv
.globl main
.p2align 1
.type main,@function
main:
.cfi_startproc
addi sp, sp, -32
.cfi_def_cfa_offset 32
sw ra, 28(sp)
sw s0, 24(sp)
sw s1, 20(sp)
sw s2, 16(sp)
sw s3, 12(sp)
.cfi_offset ra, -4
.cfi_offset s0, -8
.cfi_offset s1, -12
.cfi_offset s2, -16
.cfi_offset s3, -20
#APP
mv s0, sp
#NO_APP
lui a0, %hi(const_9)
addi s2, a0, %lo(const_9)
mv a0, s2
call ($len)@plt
mv s1, a0
li s0, 0
.LBB1_1:
lw a0, 16(s2)
add a0, a0, s0
lb a0, 0(a0)
call initchars@plt
mv s3, a0
call print@plt
addi s1, s1, -1
addi s0, s0, 4
bnez s1, .LBB1_1
mv a0, s3
call print@plt
#APP
li a7, 93 #exit system call
ecall
#NO_APP
lw ra, 28(sp)
lw s0, 24(sp)
lw s1, 20(sp)
lw s2, 16(sp)
lw s3, 12(sp)
addi sp, sp, 32
ret
.Lfunc_end1:
.size main, .Lfunc_end1-main
.cfi_endproc
```
</pre>
<img width="1px" height="1px" alt="" src="http://email.email.llvm.org/o/eJzNW9tu4zgS_RrnhbAhUZIvD3noJBhsA7uTBnYW2DeDkihbE1rUilQS99cvL7qQEiXbncx0D3p8EauKp4qHVUVZiWl6vv-6gJsT4BUqWELTvDgAfsQgo4TQN_mNkNcTECMYcAqqnCWvIEbJCy5SUDMpkBAkXv1o5a08cMg5OCJ2BAlK_F0W-qEPwzhbZzBGm20S48jHaQQ36xBv0wwGmxX4Q0yX0NMJCYs5A4u1py0uTwVdVpigd7AUn_KC40OFOE6XiIHlsweWb2C55Kg6YL4InhS0AC7r4qWgb8USk0yYWnhPC-9L8yq-qn_SpeZS8AD-RdOa4K9PQBgBIhiPR5rQb2fls_iqBRmtqwTvs5zgAp1wIwsX8Lf_MFwx8X7O33B-FsDF57Kif-KEi08xehGviTRZnvccM3mxRIF4ZehUEiw_8BPfZ7TaMy7-F9b3r6halWdp34QPowUM6yKnxYqfS41Bf9g8gDyA4v1pSkHAvkm-rPlN8gktGMnZtUo01vEJRaQ4lfJ7pdSrS32tAaSZBXx0fxvYS3NWIp4c_0Ax0TYXsJ25AxJ6Tgh69gOhMSJDuzZOGxvwbHQguBEfGCCyhIbgL9mzVuAGFNsrZHYXg2lpzcTThfsvgWvFdrXf50XO9_uhE0ZoRZ75PF5qY25S2pxxhnWAxUFQF9oBO_3BTOEtKIEJxOalbdVz8nTK8k8hqQPMVEB_XXrGlJLP42dj7SJBfTc_h2AcBHXiHTAUXmToHE5gYZnkqD9B0UnTP4WjLjSTQf11WSo6mc8jqTZ2VRI1vm4VbleMB-AcpHXBH3A2GEwd3QIbmEDms-rQI5GfOC15JSbZKgnZlqshuVQugk_h-Cn8doCZCv-vy-6V7HQ_j99mSz_JZ1ezPcnwEUAHx91ODFi-HDYPY5qb6DcPmpISzjSRp1xxUntC2EH21n8pxfee8hi_c1wVwucrapKt739QH87oO9OLrR58TD38mHr0MfX1x9Q3H1PfXZfPwU9J6MEooR8wxwSfcMEl9fMipnWRMrkHFtFDCN6lWCS3E7C_qznFhKvGaynR7rT2w86RHgwVFaiyyl8Rx6Au5I2NdI_StOqiZ8wIkgWE7_99X0SPvqdufTwCRPJDIQ4YxgZMcUJQha857zmz7pVZ25rrleapNHfEqFxJO8rKzgXowhpK5eSI5A2dbT5l48JxqaAivK8uCC1OXFW0Wj0_P1wW-p0W-LLUU-6cbzbRa7ACaoJ4F_VJWcW_SyI_NH2T0be6Mk7k-0ewWq1GE6gSqVhEcNH50N3wmgyaoHzBB_Jlzad9cCd87cIJvWA9vs39WcZMqms0KgAzpJ1UV8PbWdHbDSvUKihjXsnjoEok-H_k5pk75eJHtC_iFkMmoSftPs6b6vuLUN0uXumMuE84rZjKm6gscaHul_fJ0hfJsrnvKWfQfNMB1HM2pxKRjkVCFQrXCXf3UtdRFERjYel3jDNa4f0J5UWvW9SENLO1Yczyot8IltJW1Yu2KOpXgmJMvEXwpa1ZHOUEJEiYVTYQOwGWpxhnmcjW8o44qXOAVA3a-jsoioU0tRNFBTBfNpPgO66oqh1tEVFv0OQZMGaYSutXQDm9ijkVlEPpANK9ee2gUMjKDmNzkbyBCsmLvsTISomgN5YDpjT0q79uhyrMJ93Tr3VRYSRqzfgW72CRPnN1FOLMQDy3CGKD0FL3scIkTZCiajPIxEbAVsOhiKhULAO6kyUUpS3Tp2VDc7JLDV-jo3vVWNRtJH9-mM8PepLuWDG5-b_Ybl7MOkYPdslyg9ryYX29D72F4elIVbwvlt1NH_uR5KNDuUFj2dgqG4pUF-ptM-eQQbrNZHXcHGmlTbVZWqm4AorJckx98L0Ry31Jc3Djf_LXvbLCKWt-rouaDaN9V1-gb2H19bGvPOYabPTQkNjUEUfLriFv1Ha2TdAl3Nau3kZ5cipBgftAtHpyZltBbxv7cDBHjAvEG5DUOiiE9syhsWG3ZinqCOIHtoa9BZuy1djq707Z1PTXDgen5otaqM5QbcbT96rrHoGltLW9fLRgb2xZzWBZOkwMJoV1LvP6rfIDp40WmLF_RjsD-qOdIS591s5o913rD5xMSxMuNVEYJKamtXaV9ulOvIVgR0N1j3pDyfiP0sboGgzGAQs-LWCD7AHDnx-w8JYOiYhebSODthPpBgb4PeeAnRnHJ6WmmhmsPk13CaLTUeaHdxrahy3M-H8tQFYXCReoQdupqqdN8krES21GEQpWiokeANwC-UhIfFYi8nkTmgkZWoKYpmcxb81wL6taGipEERcZ9r2xlhdaucwJPdRYWujZIp82eauo6OBFF6wt5xxXcoVWAycQY_gUk3PrzE6dB4jsGaUb3dUSqlsi4qPfX9Qty65xWCxiGwMtoq63PZyUT7J8zziquMjiSXdZtm7izWw3l-vQ1hKd4z7J0J5mGRPLYgyzN9mUqj5WONT2sZZyo6SFlr2qIMaXb9-6r6dXac5rUBhCvz_vTTki0eqTgGfD0Bej9QiGMQrHIMXJohsWi3jMhURX0nbDOGm5TppQt7QxZQBHUyrqS-e2bc-zk3uQcDsayG_m6qDOOtIi1FrqdekPEKmrcjPPhGg7Gv1TruU_Hx78fWOv_WLQy8Q2tk-M2Tv7IoC_iX8AHQRV1cbq5N9pNQg2Mlwp8Hdz1OHE2Ie_ZJkNp33JO_nRCCrRZIX9gkBzoqGHcG4pnSvpj7lFYmN_DBE1xOsbBJt1bODOFAugyQI4wQKHhWZ6XWzsqbUinHJqdmX7UA25AN2Eo6-4YkeU0rfmICbyd5_xWxNxgfsVUuatPWBFJDAjEnxKRAb5UXvZVFU9PKqrrSxuE8xMGp1N3I6iYCR9eROicVeWnL2ooVYqWLH8u1GZgCG2tOuarA_islGQXOX9H_QNixVT3XQGvgL2JukrS_ryWa2LHD3zo7xpJmovfUHnYaFVT3H-YlU2gLbWoMoaw0aVdWRnNcqmMq8e9Sdqhh6FE-zUo8HEppyt7uagxrbcugebQgXdo1CPrt2jCtoSelOb5uqm4qbioEFdLA66huvJe--urP1sVPvzzhXvmiKslxMO4A9KDjPsf6BuaMTBAPFMbmsD2dwpHbQq7WgLUbz2xIp18WfOhGyGPLgGyN-WZB37lszuWzK7b8nsviWz-9aRi4xc83ck97v0Pkh3wQ7d8ZwTfP9vKh99X3vLZzmq_zRg9FcBIqkmL6Ck8oH9Si5FUhOkjnzqx0p5JmvPW-yursj9kfOSSeiq6B9yfqzjVUJP4ot6Ul-_LfuH6nPGaiyfuY8iL_LvjvdenHo48mDghbG322WbLFgnfrCFnrfNErS9Uyc-di9_cYme7vJ76EHohUIehqEHV1sYhfEmWGeZh4J4l8ofVkWMyEr99EOrw111rzDE9UHuKfmjJOsHxelQlCOMW_uo5kda3b_m8tci-ScBnnenMN8rwP8H8QXYdg">