[llvm-bugs] [Bug 24756] New: LLVM remove one must instruction to produce wrong result in optimization under global register variable condition
via llvm-bugs
llvm-bugs at lists.llvm.org
Tue Sep 8 23:05:46 PDT 2015
https://llvm.org/bugs/show_bug.cgi?id=24756
Bug ID: 24756
Summary: LLVM remove one must instruction to produce wrong
result in optimization under global register variable
condition
Product: tools
Version: 3.6
Hardware: Other
OS: Linux
Status: NEW
Severity: normal
Priority: P
Component: opt
Assignee: unassignedbugs at nondot.org
Reporter: bluechristlove at 163.com
CC: llvm-bugs at lists.llvm.org
Classification: Unclassified
Firstly, let us see follow simple example:
[Example]
#include <stdio.h>
register signed int ina asm("r21");
int main()
{
ina = -244;
__asm("addi 21,21,5" : "=r"(ina) : "r"(ina) );
printf("ina: %d\n", ina);
}
[/Example]
We specific global variable as register r21, then we read from register r21
and add value 5 to r21, then print the value of ina.
The expected value is -239.
When we emit its llvm-ir in O0:
[LLVM-IR-O0]
; ModuleID = 't.c'
target datalayout = "e-m:e-i64:64-n32:64"
target triple = "powerpc64le-unknown-linux-gnu"
@.str = private unnamed_addr constant [9 x i8] c"ina: %d\0A\00", align 1
; Function Attrs: nounwind
define signext i32 @main() #0 {
entry:
call void @llvm.write_register.i32(metadata !0, i32 -244)
%0 = call i32 @llvm.read_register.i32(metadata !0)
%1 = call i32 asm "addi 21,21,5", "={r21},{r21}"(i32 %0) #1, !srcloc !2
call void @llvm.write_register.i32(metadata !0, i32 %1)
%2 = call i32 @llvm.read_register.i32(metadata !0)
%call = call signext i32 (i8*, ...)* @printf(i8* getelementptr inbounds ([9 x
i8]* @.str, i32 0, i32 0), i32 signext %2)
ret i32 0
}
; Function Attrs: nounwind
declare void @llvm.write_register.i32(metadata, i32) #1
; Function Attrs: nounwind readnone
declare i32 @llvm.read_register.i32(metadata) #2
declare signext i32 @printf(i8*, ...) #3
attributes #0 = { nounwind "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" "unsafe-fp-math"="false"
"use-soft-float"="false" }
attributes #1 = { nounwind }
attributes #2 = { nounwind readnone }
attributes #3 = { "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"
"unsafe-fp-math"="false" "use-soft-float"="false" }
!llvm.named.register.r21 = !{!0}
!llvm.ident = !{!1}
!0 = !{!"r21"}
!1 = !{!"clang version 3.6.1 (tags/RELEASE_361/final)"}
!2 = !{i32 95}
[LLVM-IR-O0]
It is right.
But when we emit the IR in -O2:
[LLVM-IR-O2]
....
; Function Attrs: nounwind
define signext i32 @main() #0 {
entry:
tail call void @llvm.write_register.i32(metadata !0, i32 -244)
%0 = tail call i32 @llvm.read_register.i32(metadata !0)
%1 = tail call i32 asm "addi 21,21,5", "={r21},{r21}"(i32 %0) #1, !srcloc !2
tail call void @llvm.write_register.i32(metadata !0, i32 %1)
%call = tail call signext i32 (i8*, ...)* @printf(i8* getelementptr inbounds
([9 x i8]* @.str, i64 0, i64 0), i32 signext %0) #1
ret i32 0
}
....
!llvm.named.register.r21 = !{!0}
!llvm.ident = !{!1}
!0 = !{!"r21"}
!1 = !{!"clang version 3.6.1 (tags/RELEASE_361/final)"}
!2 = !{i32 95
[/LLVM-IR-O2]
Here we can see that after @llvm.write_register, we remove
%2 = call i32 @llvm.read_register.i32(metadata !0)
But in fact we have modified register 21 value, so we must call
@llvm.read_register function to read value from register 21. But llvm optimizer
remove it and use %0( which is the register 21 value before modified).
Computer Architecture:
PPC64le
OS:
Red Hat Enterprise Linux 7
--
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/20150909/52c06273/attachment.html>
More information about the llvm-bugs
mailing list