125 lines · c
1// RUN: %clang_cc1 -triple=x86_64-unknown-linux-gnu -DSTRUCT -emit-llvm %s -o - 2>&1 | FileCheck %s --check-prefix=CHECK-STRUCT2// RUN: %clang_cc1 -triple=x86_64-unknown-linux-gnu -USTRUCT -emit-llvm %s -o - 2>&1 | FileCheck %s --check-prefix=CHECK-NOSTRUCT3// RUN: not %clang_cc1 -triple=x86_64-unknown-linux-gnu -DIMPOSSIBLE_ODD -emit-llvm %s -o - 2>&1 | FileCheck %s --check-prefix=CHECK-IMPOSSIBLE_ODD4// RUN: not %clang_cc1 -triple=x86_64-unknown-linux-gnu -DIMPOSSIBLE_BIG -emit-llvm %s -o - 2>&1 | FileCheck %s --check-prefix=CHECK-IMPOSSIBLE_BIG5// RUN: %clang_cc1 -triple=x86_64-unknown-linux-gnu -DPOSSIBLE_X -emit-llvm %s -o - 2>&1 | FileCheck %s --check-prefix=CHECK-X6// RUN: not %clang_cc1 -triple=x86_64-unknown-linux-gnu -DIMPOSSIBLE_X -emit-llvm %s -o - 2>&1 | FileCheck %s --check-prefix=CHECK-IMPOSSIBLE_X7// RUN: not %clang_cc1 -triple=x86_64-unknown-linux-gnu -DIMPOSSIBLE_9BYTES -emit-llvm %s -o - 2>&1 | FileCheck %s --check-prefix=CHECK-IMPOSSIBLE_9BYTES8// 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_V29 10// Make sure Clang doesn't treat |lockval| as asm input.11void _raw_spin_lock(void) {12#ifdef STRUCT13 struct {14 unsigned short owner, next;15 } lockval;16 lockval.owner = 1;17 lockval.next = 2;18#else19 int lockval;20 lockval = 3;21#endif22 asm("nop"23 : "=r"(lockval));24}25// CHECK-LABEL: _raw_spin_lock26// CHECK-LABEL: entry:27 28// CHECK-STRUCT: %lockval = alloca %struct.anon, align 229// CHECK-STRUCT: store i16 130// CHECK-STRUCT: store i16 231// CHECK-STRUCT: [[RES:%[0-9]+]] = call i32 asm "nop", "=r,~{dirflag},~{fpsr},~{flags}"()32// CHECK-STRUCT: store i32 [[RES]], ptr %lockval, align 233 34// CHECK-NOSTRUCT: %lockval = alloca i32, align 435// CHECK-NOSTRUCT: store i32 336// CHECK-NOSTRUCT: [[RES:%[0-9]+]] = call i32 asm "nop", "=r,~{dirflag},~{fpsr},~{flags}"()37// CHECK-NOSTRUCT: store i32 [[RES]], ptr %lockval, align 438 39// Check Clang correctly handles a structure with padding.40void unusual_struct(void) {41 struct {42 unsigned short first;43 unsigned char second;44 } str;45 asm("nop"46 : "=r"(str));47}48 49// Check Clang reports an error if attempting to return a structure for which50// no direct conversion to a register is possible.51void odd_struct(void) {52#ifdef IMPOSSIBLE_ODD53 struct __attribute__((__packed__)) {54 unsigned short first;55 unsigned char second;56 } str;57 asm("nop"58 : "=r"(str));59#endif60}61// CHECK-IMPOSSIBLE_ODD: impossible constraint in asm: cannot store value into a register62 63// Check Clang reports an error if attempting to return a big structure via a register.64void big_struct(void) {65#ifdef IMPOSSIBLE_BIG66 struct {67 long long int v1, v2, v3, v4;68 } str;69 asm("nop"70 : "=r"(str));71#endif72}73// CHECK-IMPOSSIBLE_BIG: impossible constraint in asm: cannot store value into a register74 75// Clang is able to emit LLVM IR for an 16-byte structure.76void x_constraint_fit(void) {77#ifdef POSSIBLE_X78 struct S {79 unsigned x[4];80 } z;81 asm volatile("nop"82 : "=x"(z));83#endif84}85// CHECK-LABEL: x_constraint_fit86// CHECK-X: %z = alloca %struct.S, align 487// CHECK-X: [[RES:%[0-9]+]] = call i128 asm sideeffect "nop", "=x,~{dirflag},~{fpsr},~{flags}"()88// CHECK-X: store i128 [[RES]], ptr %z, align 489// CHECK-X: ret90 91// Clang is unable to emit LLVM IR for a 32-byte structure.92void x_constraint_nofit(void) {93#ifdef IMPOSSIBLE_X94 struct S {95 unsigned x[8];96 } z;97 asm volatile("nop"98 : "=x"(z));99#endif100}101 102// CHECK-IMPOSSIBLE_X: invalid output size for constraint103 104// http://crbug.com/999160105// 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.108void crbug_999160_regtest(void) {109#ifdef IMPOSSIBLE_9BYTES110 char buf[9];111 asm(""112 : "=r"(buf));113#endif114}115 116// CHECK-IMPOSSIBLE_9BYTES: impossible constraint in asm: cannot store value into a register117 118void crbug_999160_regtest_v2(void) {119#ifdef IMPOSSIBLE_9BYTES_V2120 char buf[9];121 asm("" : "=r"(buf) : "0"(buf));122#endif123}124// CHECK-IMPOSSIBLE_9BYTES_V2: impossible constraint in asm: cannot store value into a register125