[llvm-bugs] [Bug 32635] New: [ppc64][inlineasm][optimization] LLVM Optimize the inline asm operand away and select wrong constraint

via llvm-bugs llvm-bugs at lists.llvm.org
Wed Apr 12 02:03:56 PDT 2017


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

            Bug ID: 32635
           Summary: [ppc64][inlineasm][optimization] LLVM Optimize the
                    inline asm operand away and select wrong constraint
           Product: libraries
           Version: 4.0
          Hardware: All
                OS: Linux
            Status: NEW
          Severity: normal
          Priority: P
         Component: Scalar Optimizations
          Assignee: unassignedbugs at nondot.org
          Reporter: bluechristlove at 163.com
                CC: llvm-bugs at lists.llvm.org

Let us begin the following simple test case:

#include <stdio.h>

int main ()
{
        int i = 0;
        int j = 0x1111111;

        asm ("  lbz %0,%1       \n"     \
                : "=&r" (i)                     \
                : "g"(j)  );

        printf("%X\n",(int)i);

}


The expected output is 11. When we use clang emit the LLVM IR in the O0.

; Function Attrs: nounwind
define signext i32 @main() #0 {
entry:
  %i = alloca i32, align 4
  %j = alloca i32, align 4
  store i32 0, i32* %i, align 4
  store i32 17895697, i32* %j, align 4
  %0 = load i32, i32* %j, align 4
  %1 = call i32 asm "\09lbz $0,$1 \09\0A", "=&r,imr"(i32 %0) #2, !srcloc !1
  store i32 %1, i32* %i, align 4
  %2 = load i32, i32* %i, align 4
  %call = call signext i32 (i8*, ...) @printf(i8* getelementptr inbounds ([4 x
i8], [4 x i8]* @.str, i32 0, i32 0), i32 signext %2)
  ret i32 0
}

g constraint is expanded into "imr" and waited by LLVM backend select. In this
case, LLVM backend will select "m" constraint right. 

But things become unusal when we using optimization.

Following is the O2 / O3

; Function Attrs: nounwind
define signext i32 @main() local_unnamed_addr #0 {
entry:
  %0 = tail call i32 asm "\09lbz $0,$1 \09\0A", "=&r,imr"(i32 17895697) #2,
!srcloc !1
  %call = tail call signext i32 (i8*, ...) @printf(i8* getelementptr inbounds
([4 x i8], [4 x i8]* @.str, i64 0, i64 0), i32 signext %0)
  ret i32 0
}

We can see that the operand of constraint g is optimized away. And the operand
of constraint g becomed into one constant int i32 17895697.

However, when we have "i" "m" "r" constraint, and the operand is constant int,
the LLVM backend will select "i", though this constant int number should be
treated as memory.  Currently, if we have "m" constraint only. LLVM backend can
handle it.

; Function Attrs: nounwind
define signext i32 @main() local_unnamed_addr #0 {
entry:
  %0 = tail call i32 asm "\09lbz $0,$1 \09\0A", "=&r,m"(i32 17895697) #2,
!srcloc !1
  %call = tail call signext i32 (i8*, ...) @printf(i8* getelementptr inbounds
([4 x i8], [4 x i8]* @.str, i64 0, i64 0), i32 signext %0)
  ret i32 0
}

LLVM can know this constant int is memory address. But in our buggy case, LLVM
can not know it is memory address and will choose better constraint "i", this
obeys the user code semantic, So LLVM opt has some problem of this case...

-- 
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/20170412/9e2f3a82/attachment-0001.html>


More information about the llvm-bugs mailing list