<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 - Regression: const function hoisting not happening"
   href="https://bugs.llvm.org/show_bug.cgi?id=34208">34208</a>
          </td>
        </tr>

        <tr>
          <th>Summary</th>
          <td>Regression: const function hoisting not happening
          </td>
        </tr>

        <tr>
          <th>Product</th>
          <td>clang
          </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>normal
          </td>
        </tr>

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

        <tr>
          <th>Component</th>
          <td>LLVM Codegen
          </td>
        </tr>

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

        <tr>
          <th>Reporter</th>
          <td>nat-llvmbugs@mulle-kybernetik.com
          </td>
        </tr>

        <tr>
          <th>CC</th>
          <td>llvm-bugs@lists.llvm.org
          </td>
        </tr></table>
      <p>
        <div>
        <pre>Starting with 3.9.0 a const function is not hoisted out of the loop anymore.
Compiling this little C snippet

```
extern __attribute__(( const))  int  foo( int i);

extern int  bar( int i);


int  foobar( void)
{
   int   i;
   int   x;

   x = 0;
   for( i = 0; i < 100; i++)
   {
      x += foo( 0x2373);
      x  = bar( x);
   }
   return( x == 1848);
}
```

with `-O3 -S -emit-llvm` produces

```
; ModuleID = '/tmp/x.c'
source_filename = "/tmp/x.c"
target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"
target triple = "x86_64-unknown-freebsd10.3"

; Function Attrs: nounwind uwtable
define i32 @foobar() local_unnamed_addr #0 {
  br label %1

; <label>:1:                                      ; preds = %1, %0
  %2 = phi i32 [ 0, %0 ], [ %6, %1 ]
  %3 = phi i32 [ 0, %0 ], [ %7, %1 ]
  %4 = tail call i32 @foo(i32 9075) #3
  %5 = add nsw i32 %4, %2
  %6 = tail call i32 @bar(i32 %5) #4
  %7 = add nuw nsw i32 %3, 1
  %8 = icmp eq i32 %7, 100
  br i1 %8, label %9, label %1

; <label>:9:                                      ; preds = %1
  %10 = icmp eq i32 %6, 1848
  %11 = zext i1 %10 to i32
  ret i32 %11
}

; Function Attrs: nounwind readnone
declare i32 @foo(i32) local_unnamed_addr #1

declare i32 @bar(i32) local_unnamed_addr #2

attributes #0 = { nounwind uwtable "disable-tail-calls"="false"
"less-precise-fpmad"="false" "no-frame-pointer-elim"="true"
"no-frame-pointer-elim-non-leaf" "no-infs-fp-math"="false"
"no-jump-tables"="false" "no-nans-fp-math"="false"
"no-signed-zeros-fp-math"="false" "stack-protector-buffer-size"="8"
"target-cpu"="x86-64" "target-features"="+fxsr,+mmx,+sse,+sse2,+x87"
"unsafe-fp-math"="false" "use-soft-float"="false" }
attributes #1 = { nounwind readnone "disable-tail-calls"="false"
"less-precise-fpmad"="false" "no-frame-pointer-elim"="true"
"no-frame-pointer-elim-non-leaf" "no-infs-fp-math"="false"
"no-nans-fp-math"="false" "no-signed-zeros-fp-math"="false"
"stack-protector-buffer-size"="8" "target-cpu"="x86-64"
"target-features"="+fxsr,+mmx,+sse,+sse2,+x87" "unsafe-fp-math"="false"
"use-soft-float"="false" }
attributes #2 = { "disable-tail-calls"="false" "less-precise-fpmad"="false"
"no-frame-pointer-elim"="true" "no-frame-pointer-elim-non-leaf"
"no-infs-fp-math"="false" "no-nans-fp-math"="false"
"no-signed-zeros-fp-math"="false" "stack-protector-buffer-size"="8"
"target-cpu"="x86-64" "target-features"="+fxsr,+mmx,+sse,+sse2,+x87"
"unsafe-fp-math"="false" "use-soft-float"="false" }
attributes #3 = { nounwind readnone }
attributes #4 = { nounwind }

!llvm.ident = !{!0}

!0 = !{!"clang version 3.9.0 (tags/RELEASE_390/final)"}
```


But with clang 3.8.1 it hoists the function `foo` correctly out of the loop:

```
; ModuleID = 'x.c'
target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"
target triple = "x86_64-unknown-freebsd10.3"

; Function Attrs: nounwind uwtable
define i32 @foobar() #0 {
entry:
  %call = tail call i32 @foo(i32 9075) #3
  br label %for.body

for.body:                                         ; preds = %for.body, %entry
  %x.09 = phi i32 [ 0, %entry ], [ %call1, %for.body ]
  %i.08 = phi i32 [ 0, %entry ], [ %inc, %for.body ]
  %add = add nsw i32 %call, %x.09
  %call1 = tail call i32 @bar(i32 %add) #4
  %inc = add nuw nsw i32 %i.08, 1
  %exitcond = icmp eq i32 %inc, 100
  br i1 %exitcond, label %for.end, label %for.body

for.end:                                          ; preds = %for.body
  %call1.lcssa = phi i32 [ %call1, %for.body ]
  %cmp2 = icmp eq i32 %call1.lcssa, 1848
  %conv = zext i1 %cmp2 to i32
  ret i32 %conv
}

; Function Attrs: nounwind readnone
declare i32 @foo(i32) #1

declare i32 @bar(i32) #2

attributes #0 = { nounwind uwtable "disable-tail-calls"="false"
"less-precise-fpmad"="false" "no-frame-pointer-elim"="true"
"no-frame-pointer-elim-non-leaf" "no-infs-fp-math"="false"
"no-nans-fp-math"="false" "stack-protector-buffer-size"="8"
"target-cpu"="x86-64" "target-features"="+fxsr,+mmx,+sse,+sse2"
"unsafe-fp-math"="false" "use-soft-float"="false" }
attributes #1 = { nounwind readnone "disable-tail-calls"="false"
"less-precise-fpmad"="false" "no-frame-pointer-elim"="true"
"no-frame-pointer-elim-non-leaf" "no-infs-fp-math"="false"
"no-nans-fp-math"="false" "stack-protector-buffer-size"="8"
"target-cpu"="x86-64" "target-features"="+fxsr,+mmx,+sse,+sse2"
"unsafe-fp-math"="false" "use-soft-float"="false" }
attributes #2 = { "disable-tail-calls"="false" "less-precise-fpmad"="false"
"no-frame-pointer-elim"="true" "no-frame-pointer-elim-non-leaf"
"no-infs-fp-math"="false" "no-nans-fp-math"="false"
"stack-protector-buffer-size"="8" "target-cpu"="x86-64"
"target-features"="+fxsr,+mmx,+sse,+sse2" "unsafe-fp-math"="false"
"use-soft-float"="false" }
attributes #3 = { nounwind readnone }
attributes #4 = { nounwind }

!llvm.ident = !{!0}

!0 = !{!"clang version 3.8.1 (tags/RELEASE_381/final)"}
```

If you remove the line `x = bar( x);` from the loop, the optimizer doesn't have
the problem anymore.

P.S. Do not use <a href="https://godbolt.org">https://godbolt.org</a> to test this, for some reasons it gives
different results.</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>