llvm / llvm-project

The LLVM Project is a collection of modular and reusable compiler and toolchain technologies.
http://llvm.org
Other
28.02k stars 11.57k forks source link

[RISC-V] i128 shift on RV32 calls __ashldi3 with out-of-range shift #57988

Open Amanieu opened 1 year ago

Amanieu commented 1 year ago

LLVM IR:

define i128 @shift_128(i32 %0) #0 {
  %2 = zext i32 %0 to i128
  %3 = shl i128 1, %2
  ret i128 %3
}

attributes #0 = { minsize nounwind optsize }

This generates this call to __ashldi3 at the start of the function. The value in a2 passed to __ashldi3 is out of range if the shift amount is less than 64. The documentation for __ashldi3 explicitly says that the shift amount must be between 0 and 63 inclusive.

    addi    a2, a1, -64
    li  a0, 1
    li  a1, 0
    call    __ashldi3@plt
llvmbot commented 1 year ago

@llvm/issue-subscribers-backend-risc-v

jrtc27 commented 1 year ago

This seems to be a generic problem in DAGTypeLegalizer::ExpandShiftWithUnknownAmountBit, it assumes it can just blindly select both cases (a1 < 64, a1 >= 64) rather than actually having a condition based on it. This is only correct in the case that those themselves are well-defined (poison allowed).

jrtc27 commented 1 year ago

(https://godbolt.org/z/Yd1dqr9nn shows the problem (they look more different only due to scheduling) on i386, arm and riscv32).

topperc commented 1 year ago

Candidate patch https://reviews.llvm.org/D134684