LLVM&x27;s llc生成的代码似乎不正确
我正在LLVM中编写一个函数传递,它生成IR文件。问题是,汇编代码的行为似乎不像我预期的那样。由于我是LLVM的新手,我想知道我是否误解了LLVM IR语义,或者这是LLVM&x27;s llc生成的代码似乎不正确,llvm,llvm-ir,Llvm,Llvm Ir,我正在LLVM中编写一个函数传递,它生成IR文件。问题是,汇编代码的行为似乎不像我预期的那样。由于我是LLVM的新手,我想知道我是否误解了LLVM IR语义,或者这是llc的错误行为 LLVM IR是: define void @fff(i32*) #0 { %2 = alloca i32*, align 8 %3 = alloca i32, align 4 %4 = load i8*, i8** @dirty br label %5 ; <label>:5:
llc
的错误行为
LLVM IR是:
define void @fff(i32*) #0 {
%2 = alloca i32*, align 8
%3 = alloca i32, align 4
%4 = load i8*, i8** @dirty
br label %5
; <label>:5: ; preds = %1
store i32* %0, i32** %2, align 8
%6 = load i32*, i32** %2, align 8
%7 = call i32 (i8*, ...) @printf(i8* getelementptr inbounds ([11 x i8], [11 x i8]* @.str.4, i32 0, i32 0), i32* %6)
%8 = load i32*, i32** %2, align 8
%9 = load i32, i32* %8, align 4
%readDirty = load atomic i8, i8* %4 acquire, align 8
%10 = icmp eq i8 %readDirty, 1
br i1 %10, label %Restart, label %11, !prof !3
; <label>:11: ; preds = %5
store i32 %9, i32* %3, align 4
ret void
Restart: ; preds = %5
;EDIT: bug was here. Must include label %5 as a possible destination block
indirectbr i8* blockaddress(@fff, %5), []
}
接下来,我将使用以下工具进行组装、链接和运行:
llc -filetype=obj simpleOut.ll -o out.o
gcc -o exe out.o
./exe
如果我使用address0x7ffeea51d7a8
调用函数,它将打印:
head = 0x7ffeea51d7a8
head = 0x2e889e825bf4005c
Segmentation fault: 11
x86_64汇编代码为:
;head reside in rcx
100000d60: 55 pushq %rbp
100000d61: 48 89 e5 movq %rsp, %rbp
100000d64: 53 pushq %rbx
100000d65: 48 83 ec 18 subq $24, %rsp
100000d69: 48 89 f9 movq %rdi, %rcx
100000d6c: 48 8d 3d dd 02 00 00 leaq 733(%rip), %rdi
100000d73: ff 17 callq *(%rdi)
100000d75: 48 8b 18 movq (%rax), %rbx
100000d78: 48 8d 3d c0 01 00 00 leaq 448(%rip), %rdi
100000d7f: 48 89 4d f0 movq %rcx, -16(%rbp)
100000d83: 48 8b 75 f0 movq -16(%rbp), %rsi
100000d87: b0 00 movb $0, %al
100000d89: e8 62 01 00 00 callq 354 ;call to printf, corrupt rcx
100000d8e: 48 8b 45 f0 movq -16(%rbp), %rax
100000d92: 8b 00 movl (%rax), %eax
100000d94: 80 3b 01 cmpb $1, (%rbx)
100000d97: 74 0a je 10 <_fff+0x43>
100000d99: 89 45 ec movl %eax, -20(%rbp)
100000d9c: 48 83 c4 18 addq $24, %rsp
100000da0: 5b popq %rbx
100000da1: 5d popq %rbp
100000da2: c3 retq
100000da3: 48 8d 05 ce ff ff ff leaq -50(%rip), %rax
100000daa: ff e0 jmpq *%rax ;jumps to 100000d78
100000dac: 0f 1f 40 00 nopl (%rax)
;头部位于rcx中
100000 D60:55 pushq%rbp
100000 D61:48 89 e5 movq%rsp%rbp
100000 D64:53 pushq%rbx
100000 D65:48 83欧共体18子Q$24,%rsp
100000 D69:48 89 f9 movq%rdi,%rcx
100000d6c:48 8d 3d dd 02 00 leaq 733(%rip),%rdi
100000d73:ff 17呼叫数量*(%rdi)
100000 D75:48 8b 18 movq(%rax),%rbx
100000d78:48 8d 3d c0 01 00 leaq 448(%rip),%rdi
100000 D7F:48 89 4d f0 movq%rcx,-16(%rbp)
100000d83:48 8b 75 f0 movq-16(%rbp),%rsi
100000d87:B000 movb$0,%al
100000d89:e8 62 01 00 00 callq 354;调用printf,损坏的rcx
100000d8e:48 8b 45 f0 movq-16(%rbp),%rax
100000 D92:80亿movl(%rax),%eax
100000 D94:80 3b 01 cmpb$1,(%rbx)
100000d97:74 0a je 10
100000d99:89 45 ec移动百分比eax,-20(%rbp)
100000 D9C:48 83 c4 18追加24美元,rsp%
100000 da0:50亿popq%rbx
100000 da1:5d popq%rbp
100000 da2:c3 retq
100000 DA3:48 8d 05 ce ff leaq-50(%rip),%rax
100000daa:ff e0 jmpq*%rax;跳到100000d78
100000dac:0f 1f 4000NOPL(%rax)
问题似乎是LLVM语句storei32*%0,i32**%2,align 8
即使在重新启动后也会转换为movq%rcx,-16(%rbp)
,其中寄存器rcx
已经被printf
函数损坏
如果这看起来像一个bug,我将向LLVM提交一个bug报告。只是想确认我没有误解LLVM IR
llc
版本为5.0.0,通过自制软件安装<代码>gcc(用于链接)是clang-900.0.39.2
谢谢根据,
间接br
指令应与所有可能的目标块列表一起提供。省略跳转到的BB会产生未定义的行为。间接br中的标签列表为空。我想这可能会把事情搞砸。谢谢@arrowd。我没有添加可能的目的地;一旦我修好了,问题就解决了。我想你可以把这作为一个答案。你能编辑上面的IR来指出变化吗?
;head reside in rcx
100000d60: 55 pushq %rbp
100000d61: 48 89 e5 movq %rsp, %rbp
100000d64: 53 pushq %rbx
100000d65: 48 83 ec 18 subq $24, %rsp
100000d69: 48 89 f9 movq %rdi, %rcx
100000d6c: 48 8d 3d dd 02 00 00 leaq 733(%rip), %rdi
100000d73: ff 17 callq *(%rdi)
100000d75: 48 8b 18 movq (%rax), %rbx
100000d78: 48 8d 3d c0 01 00 00 leaq 448(%rip), %rdi
100000d7f: 48 89 4d f0 movq %rcx, -16(%rbp)
100000d83: 48 8b 75 f0 movq -16(%rbp), %rsi
100000d87: b0 00 movb $0, %al
100000d89: e8 62 01 00 00 callq 354 ;call to printf, corrupt rcx
100000d8e: 48 8b 45 f0 movq -16(%rbp), %rax
100000d92: 8b 00 movl (%rax), %eax
100000d94: 80 3b 01 cmpb $1, (%rbx)
100000d97: 74 0a je 10 <_fff+0x43>
100000d99: 89 45 ec movl %eax, -20(%rbp)
100000d9c: 48 83 c4 18 addq $24, %rsp
100000da0: 5b popq %rbx
100000da1: 5d popq %rbp
100000da2: c3 retq
100000da3: 48 8d 05 ce ff ff ff leaq -50(%rip), %rax
100000daa: ff e0 jmpq *%rax ;jumps to 100000d78
100000dac: 0f 1f 40 00 nopl (%rax)