1 // REQUIRES: x86-registered-target
2 // RUN: %clang_cc1 -triple x86_64-pc-linux-gnu -O0 -emit-llvm %s -o - | FileCheck %s
3 // RUN: %clang_cc1 -triple i386-pc-linux-gnu -O0 -emit-llvm %s -o - | FileCheck %s
6 // CHECK-LABEL: define{{.*}} i32 @test1(
7 // CHECK: callbr void asm sideeffect
8 // CHECK: to label %asm.fallthrough [label %label_true, label %loop]
9 // CHECK-LABEL: asm.fallthrough:
10 asm volatile goto("testl %0, %0; jne %l1;" :: "r"(cond
)::label_true
, loop
);
11 asm volatile goto("testl %0, %0; jne %l2;" :: "r"(cond
)::label_true
, loop
);
12 // CHECK: callbr void asm sideeffect
13 // CHECK: to label %asm.fallthrough1 [label %label_true, label %loop]
14 // CHECK-LABEL: asm.fallthrough1:
23 // CHECK-LABEL: define{{.*}} i32 @test2(
24 // CHECK: callbr i32 asm sideeffect
25 // CHECK: to label %asm.fallthrough [label %label_true.split, label %loop.split]
26 // CHECK-LABEL: asm.fallthrough:
27 asm volatile goto("testl %0, %0; jne %l2;" : "=r"(cond
) : "r"(cond
) :: label_true
, loop
);
28 asm volatile goto("testl %0, %0; jne %l3;" : "=r"(cond
) : "r"(cond
) :: label_true
, loop
);
29 // CHECK: callbr i32 asm sideeffect
30 // CHECK: to label %asm.fallthrough1 [label %label_true.split2, label %loop.split3]
31 // CHECK-LABEL: asm.fallthrough1:
39 int test3(int out1
, int out2
) {
40 // CHECK-LABEL: define{{.*}} i32 @test3(
41 // CHECK: callbr { i32, i32 } asm sideeffect
42 // CHECK: to label %asm.fallthrough [label %label_true.split, label %loop.split]
43 // CHECK-LABEL: asm.fallthrough:
44 asm volatile goto("testl %0, %0; jne %l3;" : "=r"(out1
), "=r"(out2
) : "r"(out1
) :: label_true
, loop
);
45 asm volatile goto("testl %0, %0; jne %l4;" : "=r"(out1
), "=r"(out2
) : "r"(out1
) :: label_true
, loop
);
46 // CHECK: callbr { i32, i32 } asm sideeffect
47 // CHECK: to label %asm.fallthrough6 [label %label_true.split11, label %loop.split14]
48 // CHECK-LABEL: asm.fallthrough6:
56 int test4(int out1
, int out2
) {
57 // CHECK-LABEL: define{{.*}} i32 @test4(
58 // CHECK: callbr { i32, i32 } asm sideeffect "jne ${5:l}", "={si},={di},r,0,1,!i,!i
59 // CHECK: to label %asm.fallthrough [label %label_true.split, label %loop.split]
60 // CHECK-LABEL: asm.fallthrough:
62 asm volatile goto("jne %l5" : "+S"(out1
), "+D"(out2
) : "r"(out1
) :: label_true
, loop
);
64 asm volatile goto("jne %l7" : "+S"(out1
), "+D"(out2
) : "r"(out1
), "r"(out2
) :: label_true
, loop
);
65 // CHECK: callbr { i32, i32 } asm sideeffect "jne ${7:l}", "={si},={di},r,r,0,1,!i,!i
66 // CHECK: to label %asm.fallthrough6 [label %label_true.split11, label %loop.split14]
67 // CHECK-LABEL: asm.fallthrough6:
75 int test5(int addr
, int size
, int limit
) {
76 // CHECK-LABEL: define{{.*}} i32 @test5(
77 // CHECK: callbr i32 asm "add $1,$0 ; jc ${4:l} ; cmp $2,$0 ; ja ${4:l} ; ", "=r,imr,imr,0,!i
78 // CHECK: to label %asm.fallthrough [label %t_err.split]
79 // CHECK-LABEL: asm.fallthrough:
86 : "g" (size
), "g" (limit
)
94 // CHECK-LABEL: define{{.*}} i32 @test6(
95 // CHECK: callbr i32 asm sideeffect "testl $0, $0; testl $1, $1; jne ${3:l}", "={si},r,0,!i,!i,{{.*}}
96 // CHECK: to label %asm.fallthrough [label %label_true.split, label %landing.split]
97 // CHECK-LABEL: asm.fallthrough:
98 // CHECK-LABEL: landing:
100 asm volatile goto("testl %0, %0; testl %1, %1; jne %l3" : "+S"(out2
) : "r"(out1
) :: label_true
, landing
);
107 // test7 - For the output templates in the asm string (%0, %l2), GCC places
108 // hidden inputs tied to outputs ("+r" constraint) BEFORE labels. Test that foo
109 // is $2 (or rather ${2:l} because of the l output template) in the emitted asm
112 // CHECK-LABEL: define{{.*}} ptr @test7(
113 // CHECK: %1 = callbr ptr asm "# $0\0A\09# ${2:l}", "=r,0,!i,~{dirflag},~{fpsr},~{flags}"(ptr %0)
114 // CHECK-NEXT: to label %asm.fallthrough [label %foo.split]
116 asm goto ("# %0\n\t# %l2":"+r"(p
):::foo
);
121 // test8 - the same as test7, but this time we use symbolic names rather than
124 // CHECK-LABEL: define{{.*}} ptr @test8(
125 // CHECK: %1 = callbr ptr asm "# $0\0A\09# ${2:l}", "=r,0,!i,~{dirflag},~{fpsr},~{flags}"(ptr %0)
126 // CHECK-NEXT: to label %asm.fallthrough [label %foo.split]
128 asm goto ("# %0\n\t# %l[foo]":"+r"(p
):::foo
);