Skip to content

Invalid lowering of llvm.*.f128 intrinsics #44744

Description

@legrosbuffle
Bugzilla Link 45399
Version trunk
OS Linux

Extended Description

llvm.sin.f128 is incorrectly lowered to a call to sinl, which takes a f80: https://godbolt.org/z/M9fjLW

define fp128 @​bad_lowering(fp128 %a) {
  %s = call fp128 @​llvm.sin.f128(fp128 %a)
  ret fp128 %s
}

generates:

bad_lowering:
  jmp sinl

which is missing conversions from and to x86_fp80.

I expect a correct lowering to be:

define fp128 @​manual_correct_lowering(fp128 %a) {
  %t = fptrunc fp128 %a to x86_fp80
  %s = call x86_fp80 @​llvm.sin.f80(x86_fp80 %t)
  %e = fpext x86_fp80 %s to fp128
  ret fp128 %e
}
manual_correct_lowering:
  subq $24, %rsp
  callq __trunctfxf2
  fstpt (%rsp)
  callq sinl
  fstpt (%rsp)
  callq __extendxftf2
  addq $24, %rsp
  retq

Activity

  1. tgross35 commented on Aug 14, 2023

    @tgross35
    Contributor

    I started a patch for this here https://reviews.llvm.org/D157836

  2. 39 remaining items

  3. folkertdev commented on Jul 1, 2026

    @folkertdev
    Contributor

    This has been resolved since LLVM 19 https://godbolt.org/z/xGT7EKfd6. The default lowering uses a libcall.

    bad_lowering: # @bad_lowering
      jmp sinf128@PLT # TAILCALL
    manual_correct_lowering: # @manual_correct_lowering
      subq $24, %rsp
      callq __trunctfxf2@PLT
      fstpt (%rsp)
      callq sinl@PLT
      fstpt (%rsp)
      callq __extendxftf2@PLT
      addq $24, %rsp
      retq
  4. tgross35 commented on Jul 1, 2026

    @tgross35
    Contributor

    That's only on linux-gnu (IIRC there's an exception in the code), all other targets are still borked https://godbolt.org/z/PWdvEKdbM

  5. folkertdev commented on Aug 23, 2026

    @folkertdev
    Contributor

    @arsenm thanks for your work on gradually fixing this!

    From reading the commits though, it seems like LLVM will now error when the required libcall is not available. That sort of makes sense from the LLVM perspective, but for Rust (and I assume other frontends) we'd rather that it turns into a linker error, so that rust's compiler-builtins can provide its own implementation where needed.

    Rust aims to provide the f128 type across targets, not just on targets where it corresponds to long double or even just targets where Clang defined __float128 or _Float128. All targets. Hence we need a mechanism to provide the libcalls where the platform doesn't have them (yet).

  6. arsenm commented on Aug 23, 2026

    @arsenm
    Contributor

    It's kind of terrible that compiler-rt is being treated as a static, unmaintained thing and worked around with external components.

    However, I am working towards a generalized mechanism for pluggable runtime libraries. I have most of the core infrastructure implemented (#217592 is part 1). When it's done you'll be able to declare what compiler-builtins provides in tablegen and specify a module flag indicating it will be linked

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions