<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">