[LLVM][IR] Use splat syntax when printing ConstantExpr based splats. (#116856)
[llvm-project.git] / clang / test / CodeGen / X86 / x86_64-PR42672.c
blob42894c0c4cb570203e39fb750b8e9c959944868a
1 // RUN: %clang_cc1 -triple=x86_64-unknown-linux-gnu -DSTRUCT -emit-llvm %s -o - 2>&1 | FileCheck %s --check-prefix=CHECK-STRUCT
2 // RUN: %clang_cc1 -triple=x86_64-unknown-linux-gnu -USTRUCT -emit-llvm %s -o - 2>&1 | FileCheck %s --check-prefix=CHECK-NOSTRUCT
3 // RUN: not %clang_cc1 -triple=x86_64-unknown-linux-gnu -DIMPOSSIBLE_ODD -emit-llvm %s -o - 2>&1 | FileCheck %s --check-prefix=CHECK-IMPOSSIBLE_ODD
4 // RUN: not %clang_cc1 -triple=x86_64-unknown-linux-gnu -DIMPOSSIBLE_BIG -emit-llvm %s -o - 2>&1 | FileCheck %s --check-prefix=CHECK-IMPOSSIBLE_BIG
5 // RUN: %clang_cc1 -triple=x86_64-unknown-linux-gnu -DPOSSIBLE_X -emit-llvm %s -o - 2>&1 | FileCheck %s --check-prefix=CHECK-X
6 // RUN: not %clang_cc1 -triple=x86_64-unknown-linux-gnu -DIMPOSSIBLE_X -emit-llvm %s -o - 2>&1 | FileCheck %s --check-prefix=CHECK-IMPOSSIBLE_X
7 // RUN: not %clang_cc1 -triple=x86_64-unknown-linux-gnu -DIMPOSSIBLE_9BYTES -emit-llvm %s -o - 2>&1 | FileCheck %s --check-prefix=CHECK-IMPOSSIBLE_9BYTES
8 // RUN: not %clang_cc1 -triple=x86_64-unknown-linux-gnu -DIMPOSSIBLE_9BYTES_V2 -emit-llvm %s -o - 2>&1 | FileCheck %s --check-prefix=CHECK-IMPOSSIBLE_9BYTES_V2
10 // Make sure Clang doesn't treat |lockval| as asm input.
11 void _raw_spin_lock(void) {
12 #ifdef STRUCT
13 struct {
14 unsigned short owner, next;
15 } lockval;
16 lockval.owner = 1;
17 lockval.next = 2;
18 #else
19 int lockval;
20 lockval = 3;
21 #endif
22 asm("nop"
23 : "=r"(lockval));
25 // CHECK-LABEL: _raw_spin_lock
26 // CHECK-LABEL: entry:
28 // CHECK-STRUCT: %lockval = alloca %struct.anon, align 2
29 // CHECK-STRUCT: store i16 1
30 // CHECK-STRUCT: store i16 2
31 // CHECK-STRUCT: [[RES:%[0-9]+]] = call i32 asm "nop", "=r,~{dirflag},~{fpsr},~{flags}"()
32 // CHECK-STRUCT: store i32 [[RES]], ptr %lockval, align 2
34 // CHECK-NOSTRUCT: %lockval = alloca i32, align 4
35 // CHECK-NOSTRUCT: store i32 3
36 // CHECK-NOSTRUCT: [[RES:%[0-9]+]] = call i32 asm "nop", "=r,~{dirflag},~{fpsr},~{flags}"()
37 // CHECK-NOSTRUCT: store i32 [[RES]], ptr %lockval, align 4
39 // Check Clang correctly handles a structure with padding.
40 void unusual_struct(void) {
41 struct {
42 unsigned short first;
43 unsigned char second;
44 } str;
45 asm("nop"
46 : "=r"(str));
49 // Check Clang reports an error if attempting to return a structure for which
50 // no direct conversion to a register is possible.
51 void odd_struct(void) {
52 #ifdef IMPOSSIBLE_ODD
53 struct __attribute__((__packed__)) {
54 unsigned short first;
55 unsigned char second;
56 } str;
57 asm("nop"
58 : "=r"(str));
59 #endif
61 // CHECK-IMPOSSIBLE_ODD: impossible constraint in asm: cannot store value into a register
63 // Check Clang reports an error if attempting to return a big structure via a register.
64 void big_struct(void) {
65 #ifdef IMPOSSIBLE_BIG
66 struct {
67 long long int v1, v2, v3, v4;
68 } str;
69 asm("nop"
70 : "=r"(str));
71 #endif
73 // CHECK-IMPOSSIBLE_BIG: impossible constraint in asm: cannot store value into a register
75 // Clang is able to emit LLVM IR for an 16-byte structure.
76 void x_constraint_fit(void) {
77 #ifdef POSSIBLE_X
78 struct S {
79 unsigned x[4];
80 } z;
81 asm volatile("nop"
82 : "=x"(z));
83 #endif
85 // CHECK-LABEL: x_constraint_fit
86 // CHECK-X: %z = alloca %struct.S, align 4
87 // CHECK-X: [[RES:%[0-9]+]] = call i128 asm sideeffect "nop", "=x,~{dirflag},~{fpsr},~{flags}"()
88 // CHECK-X: store i128 [[RES]], ptr %z, align 4
89 // CHECK-X: ret
91 // Clang is unable to emit LLVM IR for a 32-byte structure.
92 void x_constraint_nofit(void) {
93 #ifdef IMPOSSIBLE_X
94 struct S {
95 unsigned x[8];
96 } z;
97 asm volatile("nop"
98 : "=x"(z));
99 #endif
102 // CHECK-IMPOSSIBLE_X: invalid output size for constraint
104 // http://crbug.com/999160
105 // Clang used to report the following message:
106 // "impossible constraint in asm: cannot store struct into a register"
107 // for the assembly directive below, although there's no struct.
108 void crbug_999160_regtest(void) {
109 #ifdef IMPOSSIBLE_9BYTES
110 char buf[9];
111 asm(""
112 : "=r"(buf));
113 #endif
116 // CHECK-IMPOSSIBLE_9BYTES: impossible constraint in asm: cannot store value into a register
118 void crbug_999160_regtest_v2(void) {
119 #ifdef IMPOSSIBLE_9BYTES_V2
120 char buf[9];
121 asm("" : "=r"(buf) : "0"(buf));
122 #endif
124 // CHECK-IMPOSSIBLE_9BYTES_V2: impossible constraint in asm: cannot store value into a register