[llvm-bugs] [Bug 25784] New: Optimization passes change floating-point constant on non-C locale

via llvm-bugs llvm-bugs at lists.llvm.org
Wed Dec 9 02:23:15 PST 2015


https://llvm.org/bugs/show_bug.cgi?id=25784

            Bug ID: 25784
           Summary: Optimization passes change floating-point constant on
                    non-C locale
           Product: libraries
           Version: 3.6
          Hardware: PC
                OS: Linux
            Status: NEW
          Severity: normal
          Priority: P
         Component: Scalar Optimizations
          Assignee: unassignedbugs at nondot.org
          Reporter: pitrou at free.fr
                CC: llvm-bugs at lists.llvm.org
    Classification: Unclassified

Unfortunately, I don't have a standalone reproducer for this, as I was not able
to reproduce it without invoking Numba's compile chain. The bottom line is that
somewhere during optimization passes, some floating-point data is changed if
LC_NUMERIC is not the C locale. The reproducer using Numba is the following
script:

```
import locale
import numpy as np

from numba import jit

locale.setlocale(locale.LC_ALL, ('fr_FR', 'UTF-8'))

@jit("float64(float64[:])", nopython=True)
def f(x):
    return 12.3

print(f(np.empty(0)))  # => prints "1.0"
```

When debugging the compile chain, one notices the following function:

define i32 @"__main__.f$1.array(float64,_1d,_A)"(double* nocapture noalias
%"retptr", {i8*, i32}** nocapture noalias %"excinfo", i8* nocapture noalias
%"env", i8* %"arg.x.0", i8* %"arg.x.1", i64 %"arg.x.2", i64 %"arg.x.3", double*
%"arg.x.4", i64 %"arg.x.5.0", i64 %"arg.x.6.0") 
{
entry:
  %"inserted.meminfo" = insertvalue {i8*, i8*, i64, i64, double*, [1 x i64], [1
x i64]} undef, i8* %"arg.x.0", 0
  %"inserted.parent" = insertvalue {i8*, i8*, i64, i64, double*, [1 x i64], [1
x i64]} %"inserted.meminfo", i8* %"arg.x.1", 1
  %"inserted.nitems" = insertvalue {i8*, i8*, i64, i64, double*, [1 x i64], [1
x i64]} %"inserted.parent", i64 %"arg.x.2", 2
  %"inserted.itemsize" = insertvalue {i8*, i8*, i64, i64, double*, [1 x i64],
[1 x i64]} %"inserted.nitems", i64 %"arg.x.3", 3
  %"inserted.data" = insertvalue {i8*, i8*, i64, i64, double*, [1 x i64], [1 x
i64]} %"inserted.itemsize", double* %"arg.x.4", 4
  %".12" = insertvalue [1 x i64] undef, i64 %"arg.x.5.0", 0
  %"inserted.shape" = insertvalue {i8*, i8*, i64, i64, double*, [1 x i64], [1 x
i64]} %"inserted.data", [1 x i64] %".12", 5
  %".13" = insertvalue [1 x i64] undef, i64 %"arg.x.6.0", 0
  %"inserted.strides" = insertvalue {i8*, i8*, i64, i64, double*, [1 x i64], [1
x i64]} %"inserted.shape", [1 x i64] %".13", 6
  %"x" = alloca {i8*, i8*, i64, i64, double*, [1 x i64], [1 x i64]}
  store {i8*, i8*, i64, i64, double*, [1 x i64], [1 x i64]} zeroinitializer,
{i8*, i8*, i64, i64, double*, [1 x i64], [1 x i64]}* %"x"
  %"$const0.1" = alloca double
  store double 0.0, double* %"$const0.1"
  %"$0.2" = alloca double
  store double 0.0, double* %"$0.2"
  br label %"B0"
B0:
  %"extracted.meminfo" = extractvalue {i8*, i8*, i64, i64, double*, [1 x i64],
[1 x i64]} %"inserted.strides", 0
  %"extracted.parent" = extractvalue {i8*, i8*, i64, i64, double*, [1 x i64],
[1 x i64]} %"inserted.strides", 1
  %"extracted.nitems" = extractvalue {i8*, i8*, i64, i64, double*, [1 x i64],
[1 x i64]} %"inserted.strides", 2
  %"extracted.itemsize" = extractvalue {i8*, i8*, i64, i64, double*, [1 x i64],
[1 x i64]} %"inserted.strides", 3
  %"extracted.data" = extractvalue {i8*, i8*, i64, i64, double*, [1 x i64], [1
x i64]} %"inserted.strides", 4
  %"extracted.shape" = extractvalue {i8*, i8*, i64, i64, double*, [1 x i64], [1
x i64]} %"inserted.strides", 5
  %"extracted.strides" = extractvalue {i8*, i8*, i64, i64, double*, [1 x i64],
[1 x i64]} %"inserted.strides", 6
  call void (i8*)* @"NRT_incref"(i8* %"extracted.meminfo")
  %".15" = extractvalue [1 x i64] %"extracted.shape", 0
  %".16" = extractvalue [1 x i64] %"extracted.strides", 0
  %".18" = load {i8*, i8*, i64, i64, double*, [1 x i64], [1 x i64]}* %"x"
  %"extracted.meminfo.1" = extractvalue {i8*, i8*, i64, i64, double*, [1 x
i64], [1 x i64]} %".18", 0
  %"extracted.parent.1" = extractvalue {i8*, i8*, i64, i64, double*, [1 x i64],
[1 x i64]} %".18", 1
  %"extracted.nitems.1" = extractvalue {i8*, i8*, i64, i64, double*, [1 x i64],
[1 x i64]} %".18", 2
  %"extracted.itemsize.1" = extractvalue {i8*, i8*, i64, i64, double*, [1 x
i64], [1 x i64]} %".18", 3
  %"extracted.data.1" = extractvalue {i8*, i8*, i64, i64, double*, [1 x i64],
[1 x i64]} %".18", 4
  %"extracted.shape.1" = extractvalue {i8*, i8*, i64, i64, double*, [1 x i64],
[1 x i64]} %".18", 5
  %"extracted.strides.1" = extractvalue {i8*, i8*, i64, i64, double*, [1 x
i64], [1 x i64]} %".18", 6
  call void (i8*)* @"NRT_decref"(i8* %"extracted.meminfo.1")
  %".20" = extractvalue [1 x i64] %"extracted.shape.1", 0
  %".21" = extractvalue [1 x i64] %"extracted.strides.1", 0
  store {i8*, i8*, i64, i64, double*, [1 x i64], [1 x i64]}
%"inserted.strides", {i8*, i8*, i64, i64, double*, [1 x i64], [1 x i64]}* %"x"
  %".23" = load {i8*, i8*, i64, i64, double*, [1 x i64], [1 x i64]}* %"x"
  %"extracted.meminfo.2" = extractvalue {i8*, i8*, i64, i64, double*, [1 x
i64], [1 x i64]} %".23", 0
  %"extracted.parent.2" = extractvalue {i8*, i8*, i64, i64, double*, [1 x i64],
[1 x i64]} %".23", 1
  %"extracted.nitems.2" = extractvalue {i8*, i8*, i64, i64, double*, [1 x i64],
[1 x i64]} %".23", 2
  %"extracted.itemsize.2" = extractvalue {i8*, i8*, i64, i64, double*, [1 x
i64], [1 x i64]} %".23", 3
  %"extracted.data.2" = extractvalue {i8*, i8*, i64, i64, double*, [1 x i64],
[1 x i64]} %".23", 4
  %"extracted.shape.2" = extractvalue {i8*, i8*, i64, i64, double*, [1 x i64],
[1 x i64]} %".23", 5
  %"extracted.strides.2" = extractvalue {i8*, i8*, i64, i64, double*, [1 x
i64], [1 x i64]} %".23", 6
  call void (i8*)* @"NRT_decref"(i8* %"extracted.meminfo.2")
  %".25" = extractvalue [1 x i64] %"extracted.shape.2", 0
  %".26" = extractvalue [1 x i64] %"extracted.strides.2", 0
  store {i8*, i8*, i64, i64, double*, [1 x i64], [1 x i64]} zeroinitializer,
{i8*, i8*, i64, i64, double*, [1 x i64], [1 x i64]}* %"x"
  %".29" = load double* %"$const0.1"
  store double 0x402899999999999a, double* %"$const0.1"
  %".31" = load double* %"$const0.1"
  %".33" = load double* %"$0.2"
  store double %".31", double* %"$0.2"
  %".35" = load double* %"$const0.1"
  store double 0.0, double* %"$const0.1"
  %".37" = load double* %"$0.2"
  store double %".37", double* %"retptr"
  ret i32 0
}


gets optimized into the following:

define i32 @"__main__.f$1.array(float64,_1d,_A)"(double* noalias nocapture
%retptr, { i8*, i32 }** noalias nocapture readnone %excinfo, i8* noalias
nocapture readnone %env, i8* nocapture readnone %arg.x.0, i8* nocapture
readnone %arg.x.1, i64 %arg.x.2, i64 %arg.x.3, double* nocapture readnone
%arg.x.4, i64 %arg.x.5.0, i64 %arg.x.6.0) {
entry:
  store double 1.000000e+00, double* %retptr, align 8
  ret i32 0
}


Notice how "double 0x402899999999999a" (which is 12.3 in hex representation)
has been replaced with "double 1.000000e+00".

(also, this is with LLVM 3.6.2...)

-- 
You are receiving this mail because:
You are on the CC list for the bug.
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/llvm-bugs/attachments/20151209/bcab3be4/attachment-0001.html>


More information about the llvm-bugs mailing list