<html>
    <head>
      <base href="http://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 --- - Function pointer miscompilation on ARM"
   href="http://llvm.org/bugs/show_bug.cgi?id=15520">15520</a>
          </td>
        </tr>

        <tr>
          <th>Summary</th>
          <td>Function pointer miscompilation on ARM
          </td>
        </tr>

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

        <tr>
          <th>Version</th>
          <td>trunk
          </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>release blocker
          </td>
        </tr>

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

        <tr>
          <th>Component</th>
          <td>Backend: ARM
          </td>
        </tr>

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

        <tr>
          <th>Reporter</th>
          <td>ilyoan@gmail.com
          </td>
        </tr>

        <tr>
          <th>CC</th>
          <td>llvmbugs@cs.uiuc.edu
          </td>
        </tr>

        <tr>
          <th>Classification</th>
          <td>Unclassified
          </td>
        </tr></table>
      <p>
        <div>
        <pre>LLVM r176844. I think LLVM miscompiles the code on ARM.

This is a example that reproduces the problem.

# C

typedef void(*Fn)(int);

void call(int a, int b, Fn fn) {
    int i;
    for (i = a; i < b; i++) {
        fn(i);
    }
}

Get LLVM IR by clang -S -emit-llvm -c -o fn.ll fn.c

# IR

; ModuleID = 'fn.c'
target datalayout =
"e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128-n8:16:32:64-S128"
target triple = "x86_64-unknown-linux-gnu"

define void @call(i32 %a, i32 %b, void (i32)* %fn) #0 {
entry:
  %a.addr = alloca i32, align 4
  %b.addr = alloca i32, align 4
  %fn.addr = alloca void (i32)*, align 8
  %i = alloca i32, align 4
  store i32 %a, i32* %a.addr, align 4
  store i32 %b, i32* %b.addr, align 4
  store void (i32)* %fn, void (i32)** %fn.addr, align 8
  %0 = load i32* %a.addr, align 4
  store i32 %0, i32* %i, align 4
  br label %for.cond

for.cond:                                         ; preds = %for.inc, %entry
  %1 = load i32* %i, align 4
  %2 = load i32* %b.addr, align 4
  %cmp = icmp slt i32 %1, %2
  br i1 %cmp, label %for.body, label %for.end

for.body:                                         ; preds = %for.cond
  %3 = load void (i32)** %fn.addr, align 8
  %4 = load i32* %i, align 4
  call void %3(i32 %4)
  br label %for.inc

for.inc:                                          ; preds = %for.body
  %5 = load i32* %i, align 4
  %inc = add nsw i32 %5, 1
  store i32 %inc, i32* %i, align 4
  br label %for.cond

for.end:                                          ; preds = %for.cond
  ret void
}

Get ARM assembly by llc -march=arm fn.ll

# ARM assembly

    .syntax unified
    .eabi_attribute 6, 10
    .eabi_attribute 7, 65
    .eabi_attribute 8, 1
    .eabi_attribute 9, 2
    .eabi_attribute 20, 1
    .eabi_attribute 21, 1
    .eabi_attribute 23, 3
    .eabi_attribute 24, 1
    .eabi_attribute 25, 1
    .file    "fn.bc"
    .text
    .globl    call
    .align    2
    .type    call,%function
call:                                   @ @call
@ BB#0:                                 @ %entry
    push    {r11, lr}
    mov    r11, sp
    sub    sp, sp, #24
    bic    sp, sp, #7
    str    r0, [sp, #20]
    str    r1, [sp, #16]
    str    r2, [sp, #8]
    ldr    r0, [sp, #20]
    b    .LBB0_2
.LBB0_1:                                @ %for.body
                                        @   in Loop: Header=BB0_2 Depth=1
    ldmib    sp, {r0, r1}
    mov    lr, pc
    mov    pc, #61
    ldr    r0, [sp, #4]
    add    r0, r0, #1
.LBB0_2:                                @ %entry
                                        @ =>This Inner Loop Header: Depth=1
    str    r0, [sp, #4]
    ldr    r0, [sp, #16]
    ldr    r1, [sp, #4]
    cmp    r1, r0
    blt    .LBB0_1
@ BB#3:                                 @ %for.end
    mov    sp, r11
    pop    {r11, lr}
    mov    pc, lr
.Ltmp0:
    .size    call, .Ltmp0-call

I think the third line of .LBB0_1: block should be mov pc, r1, right?</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>