<html>
    <head>
      <base href="https://bugs.llvm.org/">
    </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 - [LICM] LICM promotes real value to null in store instruction"
   href="https://bugs.llvm.org/show_bug.cgi?id=36801">36801</a>
          </td>
        </tr>

        <tr>
          <th>Summary</th>
          <td>[LICM] LICM promotes real value to null in store instruction
          </td>
        </tr>

        <tr>
          <th>Product</th>
          <td>new-bugs
          </td>
        </tr>

        <tr>
          <th>Version</th>
          <td>trunk
          </td>
        </tr>

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

        <tr>
          <th>OS</th>
          <td>All
          </td>
        </tr>

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

        <tr>
          <th>Severity</th>
          <td>enhancement
          </td>
        </tr>

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

        <tr>
          <th>Component</th>
          <td>new bugs
          </td>
        </tr>

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

        <tr>
          <th>Reporter</th>
          <td>ilia.taraban@intel.com
          </td>
        </tr>

        <tr>
          <th>CC</th>
          <td>llvm-bugs@lists.llvm.org
          </td>
        </tr></table>
      <p>
        <div>
        <pre>This test fails with wrong result after "Loop Invariant Code Motion":

================= nice.c ==============
unsigned int y = 0;

int main () {
  unsigned int i = 0, j = 0, a = 0;
  unsigned int gc[3] = {0};
  unsigned int *p = &a;
  scanf("");
  for (i = 2; i < 4; ++i) {
    gc[i - 1] += 1;
    for (j = i; j < 1; ++j) 
      y = (*p);
    p = &gc[i - 1];
    gc[1]++;
  }
  *p = gc[0];
  printf("res = %u\n", gc[1]);
  return 0;
}
=======================================

<span class="quote">>>> clang -v</span >
clang version 7.0.0 (trunk 327823)
Target: x86_64-unknown-linux-gnu
Thread model: posix
...

<span class="quote">>>> clang -o nice.exe nice.c -O0
>>> nice.exe</span >
res = 3
<span class="quote">>>> clang -o nice.exe nice.c -O1
>>> nice.exe</span >
res = 2

BISECT:
<span class="quote">>>> clang -o nice.exe nice.c -mllvm -opt-bisect-limit=...</span >
...
BISECT: running pass (32) Unswitch loops on loop
BISECT: running pass (33) Rotate Loops on loop
res = 3
BISECT: running pass (34) Loop Invariant Code Motion on loop
res = 2
BISECT: NOT running pass (35) Unswitch loops on loop
...

Here is "small" reproducer:
================= fine.ll ==============
define dso_local i32 @main() local_unnamed_addr {
entry:
  %gc = alloca [3 x i32], align 4
  br label %for.cond

for.cond:                                         ; preds = %for.end, %entry
  %i.0 = phi i32 [ 2, %entry ], [ %inc10, %for.end ]
  %p.0 = phi i32* [ null, %entry ], [ %arrayidx, %for.end ]
  %cmp = icmp ult i32 %i.0, 4
  br i1 %cmp, label %for.body, label %for.end11

for.body:                                         ; preds = %for.cond
  %arrayidx = getelementptr inbounds [3 x i32], [3 x i32]* %gc, i64 0, i64 0
  store i32 0, i32* %arrayidx, align 4
  br label %for.cond1

for.cond1:                                        ; preds = %for.body3,
%for.body
  %j.0 = phi i32 [ %i.0, %for.body ], [ 1, %for.body3 ]
  br i1 false, label %for.body3, label %for.end

for.body3:                                        ; preds = %for.cond1
  %0 = load i32, i32* %p.0, align 4
  br label %for.cond1

for.end:                                          ; preds = %for.cond1
  %arrayidx7 = getelementptr inbounds [3 x i32], [3 x i32]* %gc, i64 0, i64 1
  %inc10 = add i32 %i.0, 1
  br label %for.cond

for.end11:                                        ; preds = %for.cond
  %p.0.lcssa = phi i32* [ %p.0, %for.cond ]
  ret i32 0
}
=======================================

Original test does nothing.
<span class="quote">>>> opt -S -o fine.post.rotate+licm.ll -loop-rotate -licm  fine.ll
>>> clang fine.post.rotate+licm.ll && a.out</span >
Segmentation fault

After "Rotate Loops" and "Loop Invariant Code Motion", we receive "store into
null":

================= fine.post.rotate+licm.ll ==============
define dso_local i32 @main() local_unnamed_addr {
entry:
  %gc = alloca [3 x i32], align 4
  %arrayidx = getelementptr inbounds [3 x i32], [3 x i32]* %gc, i64 0, i64 0
  br label %for.body

for.body:                                         ; preds = %entry, %for.end
  %i.01 = phi i32 [ 2, %entry ], [ %inc10, %for.end ]
  br i1 false, label %for.body3.lr.ph, label %for.end

for.body3.lr.ph:                                  ; preds = %for.body
  br label %for.body3

for.body3:                                        ; preds = %for.body3.lr.ph,
%for.body3
  br i1 false, label %for.body3, label %for.cond1.for.end_crit_edge

for.cond1.for.end_crit_edge:                      ; preds = %for.body3
  br label %for.end

for.end:                                          ; preds =
%for.cond1.for.end_crit_edge, %for.body
  %inc10 = add i32 %i.01, 1
  %cmp = icmp ult i32 %inc10, 4
  br i1 %cmp, label %for.body, label %for.end11

for.end11:                                        ; preds = %for.end
  store i32 0, i32* null, align 4
  %arrayidx.le = getelementptr inbounds [3 x i32], [3 x i32]* %gc, i64 0, i64 0
  ret i32 0
}
=======================================

Quick debug shows that %arrayidx aliases null. But in original code %arrayidx
always refers to array %gs.
<span class="quote">>>>CurAST of Loop:
>>>Alias Set Tracker: 1 alias sets for 2 pointer values.
>>>  AliasSet[0x760ad30, 2] must alias, Mod/Ref   Pointers: (i32* null, 4), (i32* %arrayidx, 4)</span >

So maybe problem is in Loop aliasing.</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>