1 // NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py
2 // REQUIRES: x86-registered-target
3 // RUN: %clang_cc1 -triple x86_64-pc-linux-gnu -O0 -emit-llvm %s -o - | FileCheck %s
5 // CHECK-LABEL: @test0(
7 // CHECK-NEXT: [[RET:%.*]] = alloca i32, align 4
8 // CHECK-NEXT: [[TMP0:%.*]] = callbr i32 asm "", "=r,!i,~{dirflag},~{fpsr},~{flags}"() #[[ATTR1:[0-9]+]]
9 // CHECK-NEXT: to label [[ASM_FALLTHROUGH:%.*]] [label %z.split], !srcloc !2
10 // CHECK: asm.fallthrough:
11 // CHECK-NEXT: store i32 [[TMP0]], ptr [[RET]], align 4
12 // CHECK-NEXT: store i32 42, ptr [[RET]], align 4
13 // CHECK-NEXT: br label [[Z:%.*]]
15 // CHECK-NEXT: [[TMP1:%.*]] = load i32, ptr [[RET]], align 4
16 // CHECK-NEXT: ret i32 [[TMP1]]
18 // CHECK-NEXT: store i32 [[TMP0]], ptr [[RET]], align 4
19 // CHECK-NEXT: br label [[Z]]
23 asm goto ("" : "=r"(ret
):::z
);
29 // CHECK-LABEL: @test1(
31 // CHECK-NEXT: [[RET:%.*]] = alloca i32, align 4
32 // CHECK-NEXT: [[B:%.*]] = alloca i32, align 4
33 // CHECK-NEXT: [[TMP0:%.*]] = callbr { i32, i32 } asm "", "=r,=r,!i,~{dirflag},~{fpsr},~{flags}"() #[[ATTR1]]
34 // CHECK-NEXT: to label [[ASM_FALLTHROUGH:%.*]] [label %z.split], !srcloc !3
35 // CHECK: asm.fallthrough:
36 // CHECK-NEXT: [[ASMRESULT:%.*]] = extractvalue { i32, i32 } [[TMP0]], 0
37 // CHECK-NEXT: [[ASMRESULT1:%.*]] = extractvalue { i32, i32 } [[TMP0]], 1
38 // CHECK-NEXT: store i32 [[ASMRESULT]], ptr [[RET]], align 4
39 // CHECK-NEXT: store i32 [[ASMRESULT1]], ptr [[B]], align 4
40 // CHECK-NEXT: store i32 42, ptr [[RET]], align 4
41 // CHECK-NEXT: br label [[Z:%.*]]
43 // CHECK-NEXT: [[TMP1:%.*]] = load i32, ptr [[RET]], align 4
44 // CHECK-NEXT: ret i32 [[TMP1]]
46 // CHECK-NEXT: [[ASMRESULT2:%.*]] = extractvalue { i32, i32 } [[TMP0]], 0
47 // CHECK-NEXT: [[ASMRESULT3:%.*]] = extractvalue { i32, i32 } [[TMP0]], 1
48 // CHECK-NEXT: store i32 [[ASMRESULT2]], ptr [[RET]], align 4
49 // CHECK-NEXT: store i32 [[ASMRESULT3]], ptr [[B]], align 4
50 // CHECK-NEXT: br label [[Z]]
54 asm goto ("" : "=r"(ret
), "=r"(b
):::z
);
60 // CHECK-LABEL: @test2(
62 // CHECK-NEXT: [[RET:%.*]] = alloca i32, align 4
63 // CHECK-NEXT: [[B:%.*]] = alloca i32, align 4
64 // CHECK-NEXT: [[TMP0:%.*]] = callbr { i32, i32 } asm "", "=r,=r,!i,~{dirflag},~{fpsr},~{flags}"() #[[ATTR1]]
65 // CHECK-NEXT: to label [[ASM_FALLTHROUGH:%.*]] [label %z.split], !srcloc !4
66 // CHECK: asm.fallthrough:
67 // CHECK-NEXT: [[ASMRESULT:%.*]] = extractvalue { i32, i32 } [[TMP0]], 0
68 // CHECK-NEXT: [[ASMRESULT1:%.*]] = extractvalue { i32, i32 } [[TMP0]], 1
69 // CHECK-NEXT: store i32 [[ASMRESULT]], ptr [[RET]], align 4
70 // CHECK-NEXT: store i32 [[ASMRESULT1]], ptr [[B]], align 4
71 // CHECK-NEXT: [[TMP1:%.*]] = callbr { i32, i32 } asm "", "=r,=r,!i,~{dirflag},~{fpsr},~{flags}"() #[[ATTR1]]
72 // CHECK-NEXT: to label [[ASM_FALLTHROUGH4:%.*]] [label %z.split9], !srcloc !5
73 // CHECK: asm.fallthrough4:
74 // CHECK-NEXT: [[ASMRESULT5:%.*]] = extractvalue { i32, i32 } [[TMP1]], 0
75 // CHECK-NEXT: [[ASMRESULT6:%.*]] = extractvalue { i32, i32 } [[TMP1]], 1
76 // CHECK-NEXT: store i32 [[ASMRESULT5]], ptr [[RET]], align 4
77 // CHECK-NEXT: store i32 [[ASMRESULT6]], ptr [[B]], align 4
78 // CHECK-NEXT: br label [[Z:%.*]]
80 // CHECK-NEXT: [[TMP2:%.*]] = load i32, ptr [[RET]], align 4
81 // CHECK-NEXT: ret i32 [[TMP2]]
83 // CHECK-NEXT: [[ASMRESULT2:%.*]] = extractvalue { i32, i32 } [[TMP0]], 0
84 // CHECK-NEXT: [[ASMRESULT3:%.*]] = extractvalue { i32, i32 } [[TMP0]], 1
85 // CHECK-NEXT: store i32 [[ASMRESULT2]], ptr [[RET]], align 4
86 // CHECK-NEXT: store i32 [[ASMRESULT3]], ptr [[B]], align 4
87 // CHECK-NEXT: br label [[Z]]
89 // CHECK-NEXT: [[ASMRESULT7:%.*]] = extractvalue { i32, i32 } [[TMP1]], 0
90 // CHECK-NEXT: [[ASMRESULT8:%.*]] = extractvalue { i32, i32 } [[TMP1]], 1
91 // CHECK-NEXT: store i32 [[ASMRESULT7]], ptr [[RET]], align 4
92 // CHECK-NEXT: store i32 [[ASMRESULT8]], ptr [[B]], align 4
93 // CHECK-NEXT: br label [[Z]]
97 asm goto ("" : "=r"(ret
), "=r"(b
):::z
);
98 asm goto ("" : "=r"(ret
), "=r"(b
):::z
);
102 // CHECK-LABEL: @test3(
103 // CHECK-NEXT: entry:
104 // CHECK-NEXT: [[RETVAL:%.*]] = alloca i32, align 4
105 // CHECK-NEXT: [[OUT1_ADDR:%.*]] = alloca i32, align 4
106 // CHECK-NEXT: store i32 [[OUT1:%.*]], ptr [[OUT1_ADDR]], align 4
107 // CHECK-NEXT: [[TMP0:%.*]] = callbr i32 asm "", "=r,!i,!i,~{dirflag},~{fpsr},~{flags}"() #[[ATTR1]]
108 // CHECK-NEXT: to label [[ASM_FALLTHROUGH:%.*]] [label [[LABEL_TRUE_SPLIT:%.*]], label %loop.split], !srcloc !6
109 // CHECK: asm.fallthrough:
110 // CHECK-NEXT: store i32 [[TMP0]], ptr [[OUT1_ADDR]], align 4
111 // CHECK-NEXT: store i32 0, ptr [[RETVAL]], align 4
112 // CHECK-NEXT: br label [[RETURN:%.*]]
113 // CHECK: label_true.split:
114 // CHECK-NEXT: store i32 [[TMP0]], ptr [[OUT1_ADDR]], align 4
115 // CHECK-NEXT: br label [[LABEL_TRUE:%.*]]
116 // CHECK: loop.split:
117 // CHECK-NEXT: store i32 [[TMP0]], ptr [[OUT1_ADDR]], align 4
118 // CHECK-NEXT: br label [[LOOP:%.*]]
120 // CHECK-NEXT: store i32 0, ptr [[RETVAL]], align 4
121 // CHECK-NEXT: br label [[RETURN]]
122 // CHECK: label_true:
123 // CHECK-NEXT: store i32 1, ptr [[RETVAL]], align 4
124 // CHECK-NEXT: br label [[RETURN]]
126 // CHECK-NEXT: [[TMP1:%.*]] = load i32, ptr [[RETVAL]], align 4
127 // CHECK-NEXT: ret i32 [[TMP1]]
129 int test3 (int out1
) {
130 asm goto("" : "=r"(out1
)::: label_true
, loop
);
138 // CHECK-LABEL: @test4(
139 // CHECK-NEXT: entry:
140 // CHECK-NEXT: [[X:%.*]] = alloca i32, align 4
141 // CHECK-NEXT: br label [[FOO:%.*]]
143 // CHECK-NEXT: [[TMP0:%.*]] = callbr i32 asm "", "=r,!i,~{dirflag},~{fpsr},~{flags}"() #[[ATTR1]]
144 // CHECK-NEXT: to label [[ASM_FALLTHROUGH:%.*]] [label %foo.split], !srcloc !7
145 // CHECK: asm.fallthrough:
146 // CHECK-NEXT: store i32 [[TMP0]], ptr [[X]], align 4
147 // CHECK-NEXT: ret void
149 // CHECK-NEXT: store i32 [[TMP0]], ptr [[X]], align 4
150 // CHECK-NEXT: br label [[FOO]]
155 asm goto ("" : "=r"(x
):::foo
);