OLD | NEW |
1 ; RUN: pnacl-llc -O2 -mtriple=x86_64-none-nacl -filetype=obj < %s | \ | 1 ; RUN: pnacl-llc -O2 -mtriple=x86_64-none-nacl -filetype=obj < %s | \ |
2 ; RUN: llvm-objdump -d -r - | FileCheck %s | 2 ; RUN: llvm-objdump -d -r - | FileCheck %s |
3 ; RUN: pnacl-llc -O2 -mtriple=x86_64-none-nacl -filetype=obj < %s | \ | 3 ; RUN: pnacl-llc -O2 -mtriple=x86_64-none-nacl -filetype=obj < %s | \ |
4 ; RUN: llvm-objdump -d -r - | FileCheck %s --check-prefix=NOCALLRET | 4 ; RUN: llvm-objdump -d -r - | FileCheck %s --check-prefix=NOCALLRET |
5 ; RUN: pnacl-llc -O2 -mtriple=x86_64-none-nacl -filetype=obj \ | 5 ; RUN: pnacl-llc -O2 -mtriple=x86_64-none-nacl -filetype=obj \ |
6 ; RUN: -relocation-model=pic < %s | \ | 6 ; RUN: -relocation-model=pic < %s | \ |
7 ; RUN: llvm-objdump -d -r - | FileCheck %s --check-prefix=PIC | 7 ; RUN: llvm-objdump -d -r - | FileCheck %s --check-prefix=PIC |
8 | 8 |
9 ; RUN: pnacl-llc -O2 -mtriple=x86_64-none-nacl -filetype=asm < %s | \ | 9 ; RUN: pnacl-llc -O2 -mtriple=x86_64-none-nacl -filetype=asm < %s | \ |
10 ; RUN: FileCheck %s --check-prefix=ASM | 10 ; RUN: FileCheck %s --check-prefix=ASM |
(...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
56 ; ASM: callq DirectCallTarget | 56 ; ASM: callq DirectCallTarget |
57 ; The return sequence should use %r11 | 57 ; The return sequence should use %r11 |
58 ; ASM: popq %r11 | 58 ; ASM: popq %r11 |
59 ; ASM: nacljmp %r11d, %r15 | 59 ; ASM: nacljmp %r11d, %r15 |
60 | 60 |
61 declare hidden void @DirectCallTarget() #1 | 61 declare hidden void @DirectCallTarget() #1 |
62 | 62 |
63 ; Function Attrs: nounwind | 63 ; Function Attrs: nounwind |
64 define void @TestIndirectCall() #0 { | 64 define void @TestIndirectCall() #0 { |
65 entry: | 65 entry: |
66 %0 = load void ()** @IndirectCallTarget, align 4 | 66 %0 = load void ()*, void ()** @IndirectCallTarget, align 4 |
67 call void %0() | 67 call void %0() |
68 ret void | 68 ret void |
69 } | 69 } |
70 ; CHECK-LABEL: TestIndirectCall: | 70 ; CHECK-LABEL: TestIndirectCall: |
71 ; Push the immediate return address | 71 ; Push the immediate return address |
72 ; CHECK: pushq $0 | 72 ; CHECK: pushq $0 |
73 ; CHECK-NEXT: .text | 73 ; CHECK-NEXT: .text |
74 ; Fixed sequence for indirect jump | 74 ; Fixed sequence for indirect jump |
75 ; CHECK: andl $-32, %r11d | 75 ; CHECK: andl $-32, %r11d |
76 ; CHECK-NEXT: addq %r15, %r11 | 76 ; CHECK-NEXT: addq %r15, %r11 |
(...skipping 10 matching lines...) Expand all Loading... |
87 ; PIC: andl $-32, %r11d | 87 ; PIC: andl $-32, %r11d |
88 ; PIC-NEXT: addq %r15, %r11 | 88 ; PIC-NEXT: addq %r15, %r11 |
89 ; PIC-NEXT: jmpq *%r11 | 89 ; PIC-NEXT: jmpq *%r11 |
90 | 90 |
91 ; Function Attrs: nounwind | 91 ; Function Attrs: nounwind |
92 define void @TestMaskedFramePointer(i32 %Arg) #0 { | 92 define void @TestMaskedFramePointer(i32 %Arg) #0 { |
93 entry: | 93 entry: |
94 %Arg.addr = alloca i32, align 4 | 94 %Arg.addr = alloca i32, align 4 |
95 %Tmp = alloca i8*, align 4 | 95 %Tmp = alloca i8*, align 4 |
96 store i32 %Arg, i32* %Arg.addr, align 4 | 96 store i32 %Arg, i32* %Arg.addr, align 4 |
97 %0 = load i32* %Arg.addr, align 4 | 97 %0 = load i32, i32* %Arg.addr, align 4 |
98 %1 = alloca i8, i32 %0 | 98 %1 = alloca i8, i32 %0 |
99 store i8* %1, i8** %Tmp, align 4 | 99 store i8* %1, i8** %Tmp, align 4 |
100 %2 = load i8** %Tmp, align 4 | 100 %2 = load i8*, i8** %Tmp, align 4 |
101 call void @Consume(i8* %2) | 101 call void @Consume(i8* %2) |
102 ret void | 102 ret void |
103 } | 103 } |
104 ; Verify that the old frame pointer isn't leaked when saved | 104 ; Verify that the old frame pointer isn't leaked when saved |
105 ; CHECK: TestMaskedFramePointer: | 105 ; CHECK: TestMaskedFramePointer: |
106 ; CHECK: movl %ebp, %eax | 106 ; CHECK: movl %ebp, %eax |
107 ; CHECK: pushq %rax | 107 ; CHECK: pushq %rax |
108 ; CHECK: movq %rsp, %rbp | 108 ; CHECK: movq %rsp, %rbp |
109 | 109 |
110 declare void @Consume(i8*) #1 | 110 declare void @Consume(i8*) #1 |
111 | 111 |
112 ; Function Attrs: nounwind | 112 ; Function Attrs: nounwind |
113 define void @TestMaskedFramePointerVarargs(i32 %Arg, ...) #0 { | 113 define void @TestMaskedFramePointerVarargs(i32 %Arg, ...) #0 { |
114 entry: | 114 entry: |
115 %Arg.addr = alloca i32, align 4 | 115 %Arg.addr = alloca i32, align 4 |
116 %Tmp = alloca i8*, align 4 | 116 %Tmp = alloca i8*, align 4 |
117 store i32 %Arg, i32* %Arg.addr, align 4 | 117 store i32 %Arg, i32* %Arg.addr, align 4 |
118 %0 = load i32* %Arg.addr, align 4 | 118 %0 = load i32, i32* %Arg.addr, align 4 |
119 %1 = alloca i8, i32 %0 | 119 %1 = alloca i8, i32 %0 |
120 store i8* %1, i8** %Tmp, align 4 | 120 store i8* %1, i8** %Tmp, align 4 |
121 %2 = load i8** %Tmp, align 4 | 121 %2 = load i8*, i8** %Tmp, align 4 |
122 call void @Consume(i8* %2) | 122 call void @Consume(i8* %2) |
123 ret void | 123 ret void |
124 } | 124 } |
125 ; Verify use of r10 instead of rax in the presence of varargs, | 125 ; Verify use of r10 instead of rax in the presence of varargs, |
126 ; when saving the old rbp. | 126 ; when saving the old rbp. |
127 ; CHECK: TestMaskedFramePointerVarargs: | 127 ; CHECK: TestMaskedFramePointerVarargs: |
128 ; CHECK: movl %ebp, %r10d | 128 ; CHECK: movl %ebp, %r10d |
129 ; CHECK: pushq %r10 | 129 ; CHECK: pushq %r10 |
130 ; CHECK: movq %rsp, %rbp | 130 ; CHECK: movq %rsp, %rbp |
131 | 131 |
132 ; Function Attrs: nounwind | 132 ; Function Attrs: nounwind |
133 define void @TestIndirectJump(i32 %Arg) #0 { | 133 define void @TestIndirectJump(i32 %Arg) #0 { |
134 entry: | 134 entry: |
135 %Arg.addr = alloca i32, align 4 | 135 %Arg.addr = alloca i32, align 4 |
136 store i32 %Arg, i32* %Arg.addr, align 4 | 136 store i32 %Arg, i32* %Arg.addr, align 4 |
137 %0 = load i32* %Arg.addr, align 4 | 137 %0 = load i32, i32* %Arg.addr, align 4 |
138 switch i32 %0, label %sw.epilog [ | 138 switch i32 %0, label %sw.epilog [ |
139 i32 2, label %sw.bb | 139 i32 2, label %sw.bb |
140 i32 3, label %sw.bb1 | 140 i32 3, label %sw.bb1 |
141 i32 5, label %sw.bb3 | 141 i32 5, label %sw.bb3 |
142 i32 7, label %sw.bb5 | 142 i32 7, label %sw.bb5 |
143 i32 11, label %sw.bb7 | 143 i32 11, label %sw.bb7 |
144 ] | 144 ] |
145 | 145 |
146 sw.bb: ; preds = %entry | 146 sw.bb: ; preds = %entry |
147 %call = call i32 @puts(i8* getelementptr inbounds ([8 x i8]* @.str, i32 0, i32
0)) | 147 %call = call i32 @puts(i8* getelementptr inbounds ([8 x i8], [8 x i8]* @.str,
i32 0, i32 0)) |
148 br label %sw.epilog | 148 br label %sw.epilog |
149 | 149 |
150 sw.bb1: ; preds = %entry | 150 sw.bb1: ; preds = %entry |
151 %call2 = call i32 @puts(i8* getelementptr inbounds ([8 x i8]* @.str1, i32 0, i
32 0)) | 151 %call2 = call i32 @puts(i8* getelementptr inbounds ([8 x i8], [8 x i8]* @.str1
, i32 0, i32 0)) |
152 br label %sw.epilog | 152 br label %sw.epilog |
153 | 153 |
154 sw.bb3: ; preds = %entry | 154 sw.bb3: ; preds = %entry |
155 %call4 = call i32 @puts(i8* getelementptr inbounds ([8 x i8]* @.str2, i32 0, i
32 0)) | 155 %call4 = call i32 @puts(i8* getelementptr inbounds ([8 x i8], [8 x i8]* @.str2
, i32 0, i32 0)) |
156 br label %sw.epilog | 156 br label %sw.epilog |
157 | 157 |
158 sw.bb5: ; preds = %entry | 158 sw.bb5: ; preds = %entry |
159 %call6 = call i32 @puts(i8* getelementptr inbounds ([8 x i8]* @.str3, i32 0, i
32 0)) | 159 %call6 = call i32 @puts(i8* getelementptr inbounds ([8 x i8], [8 x i8]* @.str3
, i32 0, i32 0)) |
160 br label %sw.epilog | 160 br label %sw.epilog |
161 | 161 |
162 sw.bb7: ; preds = %entry | 162 sw.bb7: ; preds = %entry |
163 %call8 = call i32 @puts(i8* getelementptr inbounds ([8 x i8]* @.str4, i32 0, i
32 0)) | 163 %call8 = call i32 @puts(i8* getelementptr inbounds ([8 x i8], [8 x i8]* @.str4
, i32 0, i32 0)) |
164 br label %sw.epilog | 164 br label %sw.epilog |
165 | 165 |
166 sw.epilog: ; preds = %entry, %sw.bb7, %sw
.bb5, %sw.bb3, %sw.bb1, %sw.bb | 166 sw.epilog: ; preds = %entry, %sw.bb7, %sw
.bb5, %sw.bb3, %sw.bb1, %sw.bb |
167 ret void | 167 ret void |
168 } | 168 } |
169 ; Test the indirect jump sequence derived from a "switch" statement. | 169 ; Test the indirect jump sequence derived from a "switch" statement. |
170 ; CHECK: TestIndirectJump: | 170 ; CHECK: TestIndirectJump: |
171 ; CHECK: andl $-32, %r11d | 171 ; CHECK: andl $-32, %r11d |
172 ; CHECK-NEXT: addq %r15, %r11 | 172 ; CHECK-NEXT: addq %r15, %r11 |
173 ; CHECK-NEXT: jmpq *%r11 | 173 ; CHECK-NEXT: jmpq *%r11 |
(...skipping 20 matching lines...) Expand all Loading... |
194 ; CHECK: andl $-32, %r11d | 194 ; CHECK: andl $-32, %r11d |
195 ; CHECK-NEXT: addq %r15, %r11 | 195 ; CHECK-NEXT: addq %r15, %r11 |
196 ; CHECK-NEXT: jmpq *%r11 | 196 ; CHECK-NEXT: jmpq *%r11 |
197 | 197 |
198 attributes #0 = { nounwind "less-precise-fpmad"="false" "no-frame-pointer-elim"=
"true" "no-frame-pointer-elim-non-leaf"="true" "no-infs-fp-math"="false" "no-nan
s-fp-math"="false" "unsafe-fp-math"="false" "use-soft-float"="false" } | 198 attributes #0 = { nounwind "less-precise-fpmad"="false" "no-frame-pointer-elim"=
"true" "no-frame-pointer-elim-non-leaf"="true" "no-infs-fp-math"="false" "no-nan
s-fp-math"="false" "unsafe-fp-math"="false" "use-soft-float"="false" } |
199 attributes #1 = { "less-precise-fpmad"="false" "no-frame-pointer-elim"="true" "n
o-frame-pointer-elim-non-leaf"="true" "no-infs-fp-math"="false" "no-nans-fp-math
"="false" "unsafe-fp-math"="false" "use-soft-float"="false" } | 199 attributes #1 = { "less-precise-fpmad"="false" "no-frame-pointer-elim"="true" "n
o-frame-pointer-elim-non-leaf"="true" "no-infs-fp-math"="false" "no-nans-fp-math
"="false" "unsafe-fp-math"="false" "use-soft-float"="false" } |
200 | 200 |
201 ; Special test that no "call" or "ret" instructions are generated. | 201 ; Special test that no "call" or "ret" instructions are generated. |
202 ; NOCALLRET-NOT: call | 202 ; NOCALLRET-NOT: call |
203 ; NOCALLRET-NOT: ret | 203 ; NOCALLRET-NOT: ret |
OLD | NEW |