Skip to content

Is Changing the Floating-point environment for intrinsic/assembly code UB? #471

Open
@chorman0773

Description

@chorman0773

Disclaimer: This is not attempting to solve the general fe_setenv issue and allow changing the floating-point environment for floating-point code.

Based on rust-lang/rust#72252, it seems the following code is currently UB:

pub unsafe fn div_3_1() -> f32{
    use core::arch::x86_64::*;
    let x = _mm_set_ss(1.0);
    let y = _mm_set_ss(3.0);
    _MM_SET_ROUNDING_MODE(_MM_ROUND_TOWARD_ZERO);
    let z = _mm_div_ss(x,y);
    _MM_SET_ROUNDING_MODE(_MM_ROUND_NEAREST);
    let mut k = 0.0f32;
    _mm_store_ss(&mut k,z);
    k
}

Likewise, the following code is also considered UB:

pub unsafe fn div_3_1() -> f32{
    use core::arch::x86_64::*;
    let x = _mm_set_ss(1.0);
    let y = _mm_set_ss(3.0);
    _MM_SET_ROUNDING_MODE(_MM_ROUND_TOWARD_ZERO);
    let z;
    asm!("divss {}, {}", inlateout(xmm_reg) x => z, in(xmm_reg) y);
    _MM_SET_ROUNDING_MODE(_MM_ROUND_NEAREST);
    let mut k = 0.0f32;
    _mm_store_ss(&mut k,z);
    k
}

Both of these are suprising, as no rust-level floating-point operations are performed that would be affected by the rounding mode - only platform intrinsics or inline assembly.

These are limited examples, but a much more general example of this is a library that implements floating-point operations (including those in non-default floating-point environments from, e.g. C or C++) using a combination of software emulation, inline assembly, and platform intrinsics.

Assuming the LLVM issue mentioned in 72252 is fixed (and llvm's code generation for the llvm.x86.sse.div.ss intrinsic is fixed), can we call these examples defined behaviour, or is this code simply UB for some other reason?

Metadata

Metadata

Assignees

No one assigned

    Labels

    A-floatsTopic: concerns floating point operations/representationsS-pending-documentationStatus: The issue is "resolved," but this resolution needs documentation

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions