pcwang-thead added a comment.
Herald added a subscriber: StephenFan.

In D70401#3391561 <https://reviews.llvm.org/D70401#3391561>, @khchen wrote:

> I found 
> https://github.com/llvm/llvm-test-suite/blob/main/SingleSource/UnitTests/2003-05-26-Shorts.c
>  result is mismatched with gcc's (-march=rv32e -mabi=ilp32e).
> Did you have same issue?

I got the same issue, but it may be not this patch's problem.
Here is the reduced case:

  #include <stdio.h>
  
  unsigned long long getL() { return 0xafafafafc5c5b8a3ull; }
  int main(int argc, char **argv) {
    unsigned long long UL = getL();     /* 0xafafafafc5c5b8a3 */
    unsigned int ui = (unsigned int)UL; /* 0xc5c5b8a3 =  3318069411 */
    printf("ui = %u (0x%x)\t\tUL-ui = %lld (0x%llx)\n", ui, ui, UL - ui, UL - 
ui);
  }

GCC output is:

  ui = 3318069411 (0xc5c5b8a3)            UL-ui = -5787213829993660416 
(0xafafafaf00000000)

LLVM output is:

  ui = 3318069411 (0xc5c5b8a3)            UL-ui = 0 (0xafafafaf)

The problem is the way to pass arguments to `printf`.
GCC asm:

        li      a4,-1347440640
        addi    sp,sp,-24
        addi    a4,a4,-81
        sw      a4,8(sp)
        lw      a5,8(sp)
        li      a2,-976896000
        addi    a2,a2,-1885
        lui     a0,%hi(.LC1)
        sw      a5,0(sp)
        li      a3,0
        li      a5,0
        mv      a1,a2
        addi    a0,a0,%lo(.LC1)
        sw      ra,20(sp)
        sw      a3,4(sp)
        call    printf

LLVM asm:

        addi    sp, sp, -16
        sw      ra, 12(sp)                      # 4-byte Folded Spill
        sw      s0, 8(sp)                       # 4-byte Folded Spill
        addi    s0, sp, 16
        andi    sp, sp, -8
        lui     a0, 719611
        addi    a5, a0, -81
        sw      a5, 4(sp)
        lui     a0, %hi(.L.str)
        addi    a0, a0, %lo(.L.str)
        lui     a1, 810076
        addi    a1, a1, -1885
        sw      zero, 0(sp)
        mv      a2, a1
        mv      a4, zero
        call    printf

Both GCC and LLVM pass format string and two `ui` by `a0, a1, a2`, the 
difference is how they pass rest variadic arguments.
`UL-ui` is with 2*XLEN size, so it will be spilt to two part (low and high 
32-bits). Low part is 0x00000000, high part is 0xafafafaf.
For GCC:

  First UL-ui      : low -> a3, high -> a4
  Second UL-ui : low -> a5, high -> stack.0

For LLVM:

  First UL-ui      : low -> a4, high -> a5
  Second UL-ui : low -> stack.0, high -> stack.1

Because we use GLIBC compiled by GCC  while linking with LLVM's output, so in 
`printf`'s view:

  a3 -> undefined, so it is zero.
  a4 -> low part, 0x00000000
  a5 -> high part, 0xafafafaf
  stack.0 -> low part, 0x00000000
  stack.1 -> not used

It get `0x0000000000000000` and `0x00000000afafafaf` for two `UL-ui` (seen as 
the output).

In the ABI specification, it says (Integer Calling Convention 
<https://github.com/riscv-non-isa/riscv-elf-psabi-doc/blob/master/riscv-cc.adoc#integer-calling-convention>):

  In the base integer calling convention, variadic arguments are passed in the 
same manner as named arguments, with one exception. Variadic arguments with 
2×XLEN-bit alignment and size at most 2×XLEN bits are passed in an aligned 
register pair (i.e., the first register in the pair is even-numbered), or on 
the stack by value if none is available. After a variadic argument has been 
passed on the stack, all future arguments will also be passed on the stack 
(i.e. the last argument register may be left unused due to the aligned register 
pair rule).

And this is what LLVM do for ILP32E currently.

I saw the same issue on Github(Inconsistent variadic argument passing behavior 
between ilp32 and ilp32e for long long/double 
<https://github.com/riscv-collab/riscv-gcc/issues/148>), so shall LLVM be 
compatible with GCC's behavior?
@kito-cheng @khchen


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D70401/new/

https://reviews.llvm.org/D70401

_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to