Skip to content

[Clang] -mlink-builtin-bitcode may change FP32 denormal mode of linked module #161342

@Maetveis

Description

@Maetveis

Description

-mlink-builtin-bitcode may change the FP32 denormal mode of linked module if not explicitly specified.

Reproducer

// a.ll
declare float @add(float, float)

define float @f() #0 {
    ; The constant 0x37F0000000000000 is a denormal number in FP32
    ; 2 x F32(0x37F0000000000000) = F32(0x380000000000000) which is still denormal
    ; This is the expected result. With (incorrect) flushing of denormals we will get +0.
    %1 = call float @add(float 0x37F0000000000000, float 0x37F0000000000000)
    ret float %1
}

attributes #0 = { "denormal-fp-math"="preserve-sign,preserve-sign" }
// bc.ll
define float @add(float %a, float %b) {
    %1 = fadd float %a, %b
    ret float %1
}

Compile a.ll and link in the bitcode from bc.bc.

> llvm-as bc.ll
> clang -cc1 -fdenormal-fp-math=preserve-sign,preserve-sign -mlink-builtin-bitcode bc.bc -emit-llvm -o - a.ll

Observed behaviour

The attributes on @add have been changed to flush denormals (for F32 only):

; (...)
define internal float @add(float %a, float %b) #1 {
; (...)
; attributes #1 = { convergent "denormal-fp-math-f32"="preserve-sign,preserve-sign" ... }

This changes the behaviour of the program, for example turning on optimizations produces:

> clang -cc1 -O1 -fdenormal-fp-math=preserve-sign,preserve-sign -mlink-builtin-bitcode bc.bc -emit-llvm -o - a.ll
; (...)
define noundef float @f() local_unnamed_addr #0 {
  ret float 0.000000e+00
}

Expected behaviour

@add should have no denormal-fp-math(-f32) attributes added to it, this corresponds to the default mode as specified by IEEE.

Metadata

Metadata

Assignees

Labels

Type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions