Skip to content

s390x: incorrect use of LLVM intrinsics for vec_min/max on floats #2060

@RalfJung

Description

@RalfJung

The s390x vec_min/vec_max intrinsics on floats are meant to behave like the IEEE 754-2008 minNum/maxNum operation (with -0.0 < +0.0). However, we are currently using the llvm.minnum/llvm.maxnum intrinsic for them, which has different behavior for SNaN: LLVM is allowed to fold minnum(SNaN, x) into x but the intrinsic is supposed to always return a NaN for that situation. (I don't know if LLVM will actually ever use this freedom, but it is in the spec so who knows what it does in the future.)

We should be using llvm.s390.vfminsb and friends for this (as in 6efd06e), but that also does not work because the underlying hardware instruction is only available when the vector-enhancements-1 target feature is enabled, and whole llvm.minnum has a fallback that gets used when that target feature is missing, llvm.s390.* does not.

At the moment, I don't think there is a good way to fix this: the odd behavior of vec_min having to be available even when the underlying instruction is not available means that a fallback is needed, and that can only really be implemented in LLVM (or with a special hack in rustc codegen), but LLVM has no portable intrinsic that has the right SNaN behavior and the arch-specific intrinsic does not have the fallback behavior we need. I wonder what Clang does. (EDIT: see here for what clang does.)

Cc @uweigand

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions