<html>
    <head>
      <base href="https://llvm.org/bugs/" />
    </head>
    <body><table border="1" cellspacing="0" cellpadding="8">
        <tr>
          <th>Bug ID</th>
          <td><a class="bz_bug_link 
          bz_status_NEW "
   title="NEW --- - Optimization passes change floating-point constant on non-C locale"
   href="https://llvm.org/bugs/show_bug.cgi?id=25784">25784</a>
          </td>
        </tr>

        <tr>
          <th>Summary</th>
          <td>Optimization passes change floating-point constant on non-C locale
          </td>
        </tr>

        <tr>
          <th>Product</th>
          <td>libraries
          </td>
        </tr>

        <tr>
          <th>Version</th>
          <td>3.6
          </td>
        </tr>

        <tr>
          <th>Hardware</th>
          <td>PC
          </td>
        </tr>

        <tr>
          <th>OS</th>
          <td>Linux
          </td>
        </tr>

        <tr>
          <th>Status</th>
          <td>NEW
          </td>
        </tr>

        <tr>
          <th>Severity</th>
          <td>normal
          </td>
        </tr>

        <tr>
          <th>Priority</th>
          <td>P
          </td>
        </tr>

        <tr>
          <th>Component</th>
          <td>Scalar Optimizations
          </td>
        </tr>

        <tr>
          <th>Assignee</th>
          <td>unassignedbugs@nondot.org
          </td>
        </tr>

        <tr>
          <th>Reporter</th>
          <td>pitrou@free.fr
          </td>
        </tr>

        <tr>
          <th>CC</th>
          <td>llvm-bugs@lists.llvm.org
          </td>
        </tr>

        <tr>
          <th>Classification</th>
          <td>Unclassified
          </td>
        </tr></table>
      <p>
        <div>
        <pre>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...)</pre>
        </div>
      </p>
      <hr>
      <span>You are receiving this mail because:</span>
      
      <ul>
          <li>You are on the CC list for the bug.</li>
      </ul>
    </body>
</html>