[llvm-dev] fptosi undefined behaviour

Simon Byrne via llvm-dev llvm-dev at lists.llvm.org
Fri Jan 22 11:45:30 PST 2016


Hi all,

Consider the following snippet, the aim of which is to convert a
double to a signed i16, returning 0 if not exactly representable:

define i16 @foo(double) {
top:
  %1 = fptosi double %0 to i16
  %2 = sitofp i16 %1 to double
  %3 = fcmp une double %2, %0
  %4 = select i1 %3, i16 0, i16 %1
  ret i16 %4
}

Of course, if the value is out-of-range, the result of fptosi is
undefined. Nevertheless, the snippet works on x86 & x86_64, generating
what to me seems to be fairly efficient code for the task.

However it breaks on ARM, with foo(200000.0) => 3392. From what I can
tell (given my very limited knowledge of LLVM IR, assembler and ARM
architecture), the first line is returning a value out-of-range of the
i16 type.

1) I realise this is a somewhat silly question, but is this still
acceptable "undefined behaviour"?

2) If so, is there a way to do this in an efficient manner without
relying on undefined behaviour? (i.e. I can introduce a range check
before the fptosi call, but this would add further overhead).

(for further context, this problem originally arose in the Julia issue
https://github.com/JuliaLang/julia/issues/14549)

Thanks,
Simon


More information about the llvm-dev mailing list