mirror of
https://github.com/llvm/llvm-project.git
synced 2025-04-26 01:26:05 +00:00
[Clang] Convert some tests to opaque pointers (NFC)
This commit is contained in:
parent
58dada5f0a
commit
55a18bfe9b
@ -1,6 +1,6 @@
|
||||
// RUN: %clang_cc1 -no-opaque-pointers -triple aarch64-none-eabi -emit-llvm -o - %s | FileCheck %s --check-prefixes=CHECK,CHECK-AAPCS
|
||||
// RUN: %clang_cc1 -no-opaque-pointers -triple arm64-apple-ios7.0 -target-abi darwinpcs -emit-llvm -o - %s | FileCheck %s --check-prefixes=CHECK,CHECK-DARWIN
|
||||
// RUN: %clang_cc1 -no-opaque-pointers -triple aarch64-linux-gnu -emit-llvm -o - -x c %s | FileCheck %s --check-prefixes=CHECK,CHECK-AAPCS
|
||||
// RUN: %clang_cc1 -triple aarch64-none-eabi -emit-llvm -o - %s | FileCheck %s --check-prefixes=CHECK,CHECK-AAPCS
|
||||
// RUN: %clang_cc1 -triple arm64-apple-ios7.0 -target-abi darwinpcs -emit-llvm -o - %s | FileCheck %s --check-prefixes=CHECK,CHECK-DARWIN
|
||||
// RUN: %clang_cc1 -triple aarch64-linux-gnu -emit-llvm -o - -x c %s | FileCheck %s --check-prefixes=CHECK,CHECK-AAPCS
|
||||
|
||||
typedef struct {
|
||||
float v[2];
|
||||
@ -12,7 +12,7 @@ float f0(S0 h) {
|
||||
}
|
||||
|
||||
// CHECK: define{{.*}} float @f0_call()
|
||||
// CHECK: %call = call float @f0([2 x float] %1)
|
||||
// CHECK: %call = call float @f0([2 x float] %0)
|
||||
float f0_call(void) {
|
||||
S0 h = {1.0f, 2.0f};
|
||||
return f0(h);
|
||||
@ -27,7 +27,7 @@ double f1(S1 h) {
|
||||
}
|
||||
|
||||
// CHECK: define{{.*}} double @f1_call()
|
||||
// CHECK: %call = call double @f1([2 x double] %1
|
||||
// CHECK: %call = call double @f1([2 x double] %0
|
||||
double f1_call(void) {
|
||||
S1 h = {1.0, 2.0};
|
||||
return f1(h);
|
||||
@ -43,8 +43,8 @@ double f2(S2 h) {
|
||||
}
|
||||
|
||||
// CHECK: define{{.*}} double @f2_call()
|
||||
// CHECK-AAPCS: %call = call double @f2([2 x double] alignstack(16) %1)
|
||||
// CHECK-DARWIN: %call = call double @f2([2 x double] %1
|
||||
// CHECK-AAPCS: %call = call double @f2([2 x double] alignstack(16) %0)
|
||||
// CHECK-DARWIN: %call = call double @f2([2 x double] %0
|
||||
double f2_call(void) {
|
||||
S2 h = {1.0, 2.0};
|
||||
return f2(h);
|
||||
@ -61,8 +61,8 @@ double f3(S3 h) {
|
||||
}
|
||||
|
||||
// CHECK: define{{.*}} double @f3_call()
|
||||
// CHECK-AAPCS: %call = call double @f3([4 x double] alignstack(16) %1)
|
||||
// CHECK-DARWIN: %call = call double @f3([4 x double] %1
|
||||
// CHECK-AAPCS: %call = call double @f3([4 x double] alignstack(16) %0)
|
||||
// CHECK-DARWIN: %call = call double @f3([4 x double] %0
|
||||
double f3_call(void) {
|
||||
S3 h = {1.0, 2.0};
|
||||
return f3(h);
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -1,5 +1,5 @@
|
||||
// RUN: %clang_cc1 -no-opaque-pointers -triple x86_64-apple-darwin -emit-llvm < %s | FileCheck -enable-var-scope -check-prefixes=CHECK,X86 %s
|
||||
// RUN: %clang_cc1 -no-opaque-pointers -triple amdgcn -emit-llvm < %s | FileCheck -enable-var-scope -check-prefixes=CHECK,AMDGCN %s
|
||||
// RUN: %clang_cc1 -triple x86_64-apple-darwin -emit-llvm < %s | FileCheck -enable-var-scope -check-prefixes=CHECK,X86 %s
|
||||
// RUN: %clang_cc1 -triple amdgcn -emit-llvm < %s | FileCheck -enable-var-scope -check-prefixes=CHECK,AMDGCN %s
|
||||
|
||||
// CHECK: @foo ={{.*}} addrspace(1) global
|
||||
int foo __attribute__((address_space(1)));
|
||||
@ -11,11 +11,11 @@ int ban[10] __attribute__((address_space(1)));
|
||||
int a __attribute__((address_space(0)));
|
||||
|
||||
// CHECK-LABEL: define{{.*}} i32 @test1()
|
||||
// CHECK: load i32, i32 addrspace(1)* @foo
|
||||
// CHECK: load i32, ptr addrspace(1) @foo
|
||||
int test1(void) { return foo; }
|
||||
|
||||
// CHECK-LABEL: define{{.*}} i32 @test2(i32 noundef %i)
|
||||
// CHECK: load i32, i32 addrspace(1)*
|
||||
// CHECK: load i32, ptr addrspace(1)
|
||||
// CHECK-NEXT: ret i32
|
||||
int test2(int i) { return ban[i]; }
|
||||
|
||||
@ -23,12 +23,12 @@ int test2(int i) { return ban[i]; }
|
||||
__attribute__((address_space(2))) int *A, *B;
|
||||
|
||||
// CHECK-LABEL: define{{.*}} void @test3()
|
||||
// X86: load i32 addrspace(2)*, i32 addrspace(2)** @B
|
||||
// AMDGCN: load i32 addrspace(2)*, i32 addrspace(2)** addrspacecast (i32 addrspace(2)* addrspace(1)* @B to i32 addrspace(2)**)
|
||||
// CHECK: load i32, i32 addrspace(2)*
|
||||
// X86: load i32 addrspace(2)*, i32 addrspace(2)** @A
|
||||
// AMDGCN: load i32 addrspace(2)*, i32 addrspace(2)** addrspacecast (i32 addrspace(2)* addrspace(1)* @A to i32 addrspace(2)**)
|
||||
// CHECK: store i32 {{.*}}, i32 addrspace(2)*
|
||||
// X86: load ptr addrspace(2), ptr @B
|
||||
// AMDGCN: load ptr addrspace(2), ptr addrspacecast (ptr addrspace(1) @B to ptr)
|
||||
// CHECK: load i32, ptr addrspace(2)
|
||||
// X86: load ptr addrspace(2), ptr @A
|
||||
// AMDGCN: load ptr addrspace(2), ptr addrspacecast (ptr addrspace(1) @A to ptr)
|
||||
// CHECK: store i32 {{.*}}, ptr addrspace(2)
|
||||
void test3(void) {
|
||||
*A = *B;
|
||||
}
|
||||
@ -39,8 +39,8 @@ typedef struct {
|
||||
} MyStruct;
|
||||
|
||||
// CHECK-LABEL: define{{.*}} void @test4(
|
||||
// CHECK: call void @llvm.memcpy.p0i8.p2i8
|
||||
// CHECK: call void @llvm.memcpy.p2i8.p0i8
|
||||
// CHECK: call void @llvm.memcpy.p0.p2
|
||||
// CHECK: call void @llvm.memcpy.p2.p0
|
||||
void test4(MyStruct __attribute__((address_space(2))) *pPtr) {
|
||||
MyStruct s = pPtr[0];
|
||||
pPtr[0] = s;
|
||||
@ -50,21 +50,22 @@ void test4(MyStruct __attribute__((address_space(2))) *pPtr) {
|
||||
// pointer. Make sure no invalid bitcast is introduced.
|
||||
|
||||
// CHECK-LABEL: @void_ptr_arithmetic_test(
|
||||
// X86: [[ALLOCA:%.*]] = alloca i8 addrspace(1)*
|
||||
// X86-NEXT: store i8 addrspace(1)* %arg, i8 addrspace(1)** [[ALLOCA]]
|
||||
// X86-NEXT: load i8 addrspace(1)*, i8 addrspace(1)** [[ALLOCA]]
|
||||
// X86-NEXT: getelementptr i8, i8 addrspace(1)*
|
||||
// X86-NEXT: ret i8 addrspace(1)*
|
||||
// X86: [[ALLOCA:%.*]] = alloca ptr addrspace(1)
|
||||
// X86-NEXT: store ptr addrspace(1) %arg, ptr [[ALLOCA]]
|
||||
// X86-NEXT: load ptr addrspace(1), ptr [[ALLOCA]]
|
||||
// X86-NEXT: getelementptr i8, ptr addrspace(1)
|
||||
// X86-NEXT: ret ptr addrspace(1)
|
||||
void __attribute__((address_space(1)))*
|
||||
void_ptr_arithmetic_test(void __attribute__((address_space(1))) *arg) {
|
||||
return arg + 4;
|
||||
}
|
||||
|
||||
// CHECK-LABEL: define{{.*}} i32* @test5(
|
||||
// CHECK-LABEL: define{{.*}} ptr @test5(
|
||||
const unsigned *test5(void) {
|
||||
// Intentionally leave a part of an array uninitialized. This triggers a
|
||||
// different code path contrary to a fully initialized array.
|
||||
// CHECK: ret i32* getelementptr inbounds ([256 x i32]
|
||||
// X86: ret ptr @test5.bars
|
||||
// AMDGCN: ret ptr addrspacecast (ptr addrspace(4) @test5.bars to ptr)
|
||||
static const unsigned bars[256] = {
|
||||
0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10,
|
||||
11, 12, 13, 14, 15, 16, 17, 18, 19, 20};
|
||||
|
@ -1,5 +1,5 @@
|
||||
// RUN: %clang_cc1 -no-opaque-pointers -triple x86_64-unknown-linux-gnu -O1 -S -emit-llvm -o - %s | FileCheck %s --check-prefixes=O1
|
||||
// RUN: %clang_cc1 -no-opaque-pointers -triple x86_64-unknown-linux-gnu -O0 -S -emit-llvm -o - %s | FileCheck %s --check-prefix=O0
|
||||
// RUN: %clang_cc1 -triple x86_64-unknown-linux-gnu -O1 -S -emit-llvm -o - %s | FileCheck %s --check-prefixes=O1
|
||||
// RUN: %clang_cc1 -triple x86_64-unknown-linux-gnu -O0 -S -emit-llvm -o - %s | FileCheck %s --check-prefix=O0
|
||||
//
|
||||
// Ensure that we place appropriate lifetime markers around indirectly returned
|
||||
// temporaries, and that the lifetime.ends appear in a timely manner.
|
||||
@ -24,29 +24,23 @@ struct S bar(void) {
|
||||
// O1: %[[TMP2_ALLOCA:[^ ]+]] = alloca %struct.S
|
||||
// O1: %[[TMP3_ALLOCA:[^ ]+]] = alloca %struct.S
|
||||
|
||||
// O1: %[[P:[^ ]+]] = bitcast %struct.S* %[[TMP1_ALLOCA]] to i8*
|
||||
// O1: call void @llvm.lifetime.start.p0i8({{[^,]*}}, i8* %[[P]])
|
||||
// O1: call void @llvm.lifetime.start.p0({{[^,]*}}, ptr %[[TMP1_ALLOCA]])
|
||||
// O1: call void @foo
|
||||
r = foo();
|
||||
// O1: memcpy
|
||||
// O1: %[[P:[^ ]+]] = bitcast %struct.S* %[[TMP1_ALLOCA]] to i8*
|
||||
// O1: call void @llvm.lifetime.end.p0i8({{[^,]*}}, i8* %[[P]])
|
||||
// O1: call void @llvm.lifetime.end.p0({{[^,]*}}, ptr %[[TMP1_ALLOCA]])
|
||||
|
||||
// O1: %[[P:[^ ]+]] = bitcast %struct.S* %[[TMP2_ALLOCA]] to i8*
|
||||
// O1: call void @llvm.lifetime.start.p0i8({{[^,]*}}, i8* %[[P]])
|
||||
// O1: call void @llvm.lifetime.start.p0({{[^,]*}}, ptr %[[TMP2_ALLOCA]])
|
||||
// O1: call void @foo
|
||||
r = foo();
|
||||
// O1: memcpy
|
||||
// O1: %[[P:[^ ]+]] = bitcast %struct.S* %[[TMP2_ALLOCA]] to i8*
|
||||
// O1: call void @llvm.lifetime.end.p0i8({{[^,]*}}, i8* %[[P]])
|
||||
// O1: call void @llvm.lifetime.end.p0({{[^,]*}}, ptr %[[TMP2_ALLOCA]])
|
||||
|
||||
// O1: %[[P:[^ ]+]] = bitcast %struct.S* %[[TMP3_ALLOCA]] to i8*
|
||||
// O1: call void @llvm.lifetime.start.p0i8({{[^,]*}}, i8* %[[P]])
|
||||
// O1: call void @llvm.lifetime.start.p0({{[^,]*}}, ptr %[[TMP3_ALLOCA]])
|
||||
// O1: call void @foo
|
||||
r = foo();
|
||||
// O1: memcpy
|
||||
// O1: %[[P:[^ ]+]] = bitcast %struct.S* %[[TMP3_ALLOCA]] to i8*
|
||||
// O1: call void @llvm.lifetime.end.p0i8({{[^,]*}}, i8* %[[P]])
|
||||
// O1: call void @llvm.lifetime.end.p0({{[^,]*}}, ptr %[[TMP3_ALLOCA]])
|
||||
|
||||
return r;
|
||||
}
|
||||
@ -65,22 +59,17 @@ struct S baz(int i, volatile int *j) {
|
||||
// O1: %[[TMP2_ALLOCA:[^ ]+]] = alloca %struct.S
|
||||
|
||||
do {
|
||||
// O1: %[[P:[^ ]+]] = bitcast %struct.S* %[[TMP1_ALLOCA]] to i8*
|
||||
// O1: call void @llvm.lifetime.start.p0i8({{[^,]*}}, i8* %[[P]])
|
||||
// O1: call void @llvm.lifetime.start.p0({{[^,]*}}, ptr %[[TMP1_ALLOCA]])
|
||||
//
|
||||
// O1: %[[P:[^ ]+]] = bitcast %struct.S* %[[TMP1_ALLOCA]] to i8*
|
||||
// O1: call void @llvm.lifetime.end.p0i8({{[^,]*}}, i8* %[[P]])
|
||||
// O1: call void @llvm.lifetime.end.p0({{[^,]*}}, ptr %[[TMP1_ALLOCA]])
|
||||
//
|
||||
// O1: call void @foo_int(%struct.S* sret(%struct.S) align 4 %[[TMP1_ALLOCA]],
|
||||
// O1: call void @foo_int(ptr sret(%struct.S) align 4 %[[TMP1_ALLOCA]],
|
||||
// O1: call void @llvm.memcpy
|
||||
// O1: %[[P:[^ ]+]] = bitcast %struct.S* %[[TMP1_ALLOCA]] to i8*
|
||||
// O1: call void @llvm.lifetime.end.p0i8({{[^,]*}}, i8* %[[P]])
|
||||
// O1: %[[P:[^ ]+]] = bitcast %struct.S* %[[TMP2_ALLOCA]] to i8*
|
||||
// O1: call void @llvm.lifetime.start.p0i8({{[^,]*}}, i8* %[[P]])
|
||||
// O1: call void @foo_int(%struct.S* sret(%struct.S) align 4 %[[TMP2_ALLOCA]],
|
||||
// O1: call void @llvm.lifetime.end.p0({{[^,]*}}, ptr %[[TMP1_ALLOCA]])
|
||||
// O1: call void @llvm.lifetime.start.p0({{[^,]*}}, ptr %[[TMP2_ALLOCA]])
|
||||
// O1: call void @foo_int(ptr sret(%struct.S) align 4 %[[TMP2_ALLOCA]],
|
||||
// O1: call void @llvm.memcpy
|
||||
// O1: %[[P:[^ ]+]] = bitcast %struct.S* %[[TMP2_ALLOCA]] to i8*
|
||||
// O1: call void @llvm.lifetime.end.p0i8({{[^,]*}}, i8* %[[P]])
|
||||
// O1: call void @llvm.lifetime.end.p0({{[^,]*}}, ptr %[[TMP2_ALLOCA]])
|
||||
r = foo_int(({
|
||||
if (*j)
|
||||
break;
|
||||
|
@ -1,6 +1,6 @@
|
||||
// RUN: %clang_cc1 -no-opaque-pointers -fms-extensions -triple x86_64-windows-msvc %s -emit-llvm -o - | FileCheck %s --check-prefix=X64
|
||||
// RUN: %clang_cc1 -no-opaque-pointers -fms-extensions -triple thumbv7-windows-msvc %s -emit-llvm -o - | FileCheck %s --check-prefix=ARM
|
||||
// RUN: %clang_cc1 -no-opaque-pointers -fms-extensions -triple aarch64-windows-msvc %s -emit-llvm -o - | FileCheck %s --check-prefix=ARM
|
||||
// RUN: %clang_cc1 -fms-extensions -triple x86_64-windows-msvc %s -emit-llvm -o - | FileCheck %s --check-prefix=X64
|
||||
// RUN: %clang_cc1 -fms-extensions -triple thumbv7-windows-msvc %s -emit-llvm -o - | FileCheck %s --check-prefix=ARM
|
||||
// RUN: %clang_cc1 -fms-extensions -triple aarch64-windows-msvc %s -emit-llvm -o - | FileCheck %s --check-prefix=ARM
|
||||
|
||||
volatile unsigned char sink = 0;
|
||||
void test32(long *base, long idx) {
|
||||
@ -33,103 +33,97 @@ void test_arm(long *base, long idx) {
|
||||
}
|
||||
#endif
|
||||
|
||||
// X64-LABEL: define dso_local void @test32(i32* noundef %base, i32 noundef %idx)
|
||||
// X64: call i8 asm sideeffect "btl $2, ($1)", "={@ccc},r,r,~{cc},~{memory},~{dirflag},~{fpsr},~{flags}"(i32* %{{.*}}, i32 {{.*}})
|
||||
// X64: call i8 asm sideeffect "btcl $2, ($1)", "={@ccc},r,r,~{cc},~{memory},~{dirflag},~{fpsr},~{flags}"(i32* %{{.*}}, i32 {{.*}})
|
||||
// X64: call i8 asm sideeffect "btrl $2, ($1)", "={@ccc},r,r,~{cc},~{memory},~{dirflag},~{fpsr},~{flags}"(i32* %{{.*}}, i32 {{.*}})
|
||||
// X64: call i8 asm sideeffect "btsl $2, ($1)", "={@ccc},r,r,~{cc},~{memory},~{dirflag},~{fpsr},~{flags}"(i32* %{{.*}}, i32 {{.*}})
|
||||
// X64: call i8 asm sideeffect "lock btrl $2, ($1)", "={@ccc},r,r,~{cc},~{memory},~{dirflag},~{fpsr},~{flags}"(i32* %{{.*}}, i32 {{.*}})
|
||||
// X64: call i8 asm sideeffect "lock btsl $2, ($1)", "={@ccc},r,r,~{cc},~{memory},~{dirflag},~{fpsr},~{flags}"(i32* %{{.*}}, i32 {{.*}})
|
||||
// X64-LABEL: define dso_local void @test32(ptr noundef %base, i32 noundef %idx)
|
||||
// X64: call i8 asm sideeffect "btl $2, ($1)", "={@ccc},r,r,~{cc},~{memory},~{dirflag},~{fpsr},~{flags}"(ptr %{{.*}}, i32 {{.*}})
|
||||
// X64: call i8 asm sideeffect "btcl $2, ($1)", "={@ccc},r,r,~{cc},~{memory},~{dirflag},~{fpsr},~{flags}"(ptr %{{.*}}, i32 {{.*}})
|
||||
// X64: call i8 asm sideeffect "btrl $2, ($1)", "={@ccc},r,r,~{cc},~{memory},~{dirflag},~{fpsr},~{flags}"(ptr %{{.*}}, i32 {{.*}})
|
||||
// X64: call i8 asm sideeffect "btsl $2, ($1)", "={@ccc},r,r,~{cc},~{memory},~{dirflag},~{fpsr},~{flags}"(ptr %{{.*}}, i32 {{.*}})
|
||||
// X64: call i8 asm sideeffect "lock btrl $2, ($1)", "={@ccc},r,r,~{cc},~{memory},~{dirflag},~{fpsr},~{flags}"(ptr %{{.*}}, i32 {{.*}})
|
||||
// X64: call i8 asm sideeffect "lock btsl $2, ($1)", "={@ccc},r,r,~{cc},~{memory},~{dirflag},~{fpsr},~{flags}"(ptr %{{.*}}, i32 {{.*}})
|
||||
|
||||
// X64-LABEL: define dso_local void @test64(i64* noundef %base, i64 noundef %idx)
|
||||
// X64: call i8 asm sideeffect "btq $2, ($1)", "={@ccc},r,r,~{cc},~{memory},~{dirflag},~{fpsr},~{flags}"(i64* %{{.*}}, i64 {{.*}})
|
||||
// X64: call i8 asm sideeffect "btcq $2, ($1)", "={@ccc},r,r,~{cc},~{memory},~{dirflag},~{fpsr},~{flags}"(i64* %{{.*}}, i64 {{.*}})
|
||||
// X64: call i8 asm sideeffect "btrq $2, ($1)", "={@ccc},r,r,~{cc},~{memory},~{dirflag},~{fpsr},~{flags}"(i64* %{{.*}}, i64 {{.*}})
|
||||
// X64: call i8 asm sideeffect "btsq $2, ($1)", "={@ccc},r,r,~{cc},~{memory},~{dirflag},~{fpsr},~{flags}"(i64* %{{.*}}, i64 {{.*}})
|
||||
// X64: call i8 asm sideeffect "lock btrq $2, ($1)", "={@ccc},r,r,~{cc},~{memory},~{dirflag},~{fpsr},~{flags}"(i64* %{{.*}}, i64 {{.*}})
|
||||
// X64: call i8 asm sideeffect "lock btsq $2, ($1)", "={@ccc},r,r,~{cc},~{memory},~{dirflag},~{fpsr},~{flags}"(i64* %{{.*}}, i64 {{.*}})
|
||||
// X64-LABEL: define dso_local void @test64(ptr noundef %base, i64 noundef %idx)
|
||||
// X64: call i8 asm sideeffect "btq $2, ($1)", "={@ccc},r,r,~{cc},~{memory},~{dirflag},~{fpsr},~{flags}"(ptr %{{.*}}, i64 {{.*}})
|
||||
// X64: call i8 asm sideeffect "btcq $2, ($1)", "={@ccc},r,r,~{cc},~{memory},~{dirflag},~{fpsr},~{flags}"(ptr %{{.*}}, i64 {{.*}})
|
||||
// X64: call i8 asm sideeffect "btrq $2, ($1)", "={@ccc},r,r,~{cc},~{memory},~{dirflag},~{fpsr},~{flags}"(ptr %{{.*}}, i64 {{.*}})
|
||||
// X64: call i8 asm sideeffect "btsq $2, ($1)", "={@ccc},r,r,~{cc},~{memory},~{dirflag},~{fpsr},~{flags}"(ptr %{{.*}}, i64 {{.*}})
|
||||
// X64: call i8 asm sideeffect "lock btrq $2, ($1)", "={@ccc},r,r,~{cc},~{memory},~{dirflag},~{fpsr},~{flags}"(ptr %{{.*}}, i64 {{.*}})
|
||||
// X64: call i8 asm sideeffect "lock btsq $2, ($1)", "={@ccc},r,r,~{cc},~{memory},~{dirflag},~{fpsr},~{flags}"(ptr %{{.*}}, i64 {{.*}})
|
||||
|
||||
// ARM-LABEL: define dso_local {{.*}}void @test32(i32* noundef %base, i32 noundef %idx)
|
||||
// ARM-LABEL: define dso_local {{.*}}void @test32(ptr noundef %base, i32 noundef %idx)
|
||||
// ARM: %[[IDXHI:[^ ]*]] = ashr i32 %{{.*}}, 3
|
||||
// ARM: %[[BASE:[^ ]*]] = bitcast i32* %{{.*}} to i8*
|
||||
// ARM: %[[BYTEADDR:[^ ]*]] = getelementptr inbounds i8, i8* %[[BASE]], i32 %[[IDXHI]]
|
||||
// ARM: %[[BYTEADDR:[^ ]*]] = getelementptr inbounds i8, ptr %{{.*}}, i32 %[[IDXHI]]
|
||||
// ARM: %[[IDX8:[^ ]*]] = trunc i32 %{{.*}} to i8
|
||||
// ARM: %[[IDXLO:[^ ]*]] = and i8 %[[IDX8]], 7
|
||||
// ARM: %[[BYTE:[^ ]*]] = load i8, i8* %[[BYTEADDR]], align 1
|
||||
// ARM: %[[BYTE:[^ ]*]] = load i8, ptr %[[BYTEADDR]], align 1
|
||||
// ARM: %[[BYTESHR:[^ ]*]] = lshr i8 %[[BYTE]], %[[IDXLO]]
|
||||
// ARM: %[[RES:[^ ]*]] = and i8 %[[BYTESHR]], 1
|
||||
// ARM: store volatile i8 %[[RES]], i8* @sink, align 1
|
||||
// ARM: store volatile i8 %[[RES]], ptr @sink, align 1
|
||||
|
||||
// ARM: %[[IDXHI:[^ ]*]] = ashr i32 %{{.*}}, 3
|
||||
// ARM: %[[BASE:[^ ]*]] = bitcast i32* %{{.*}} to i8*
|
||||
// ARM: %[[BYTEADDR:[^ ]*]] = getelementptr inbounds i8, i8* %[[BASE]], i32 %[[IDXHI]]
|
||||
// ARM: %[[BYTEADDR:[^ ]*]] = getelementptr inbounds i8, ptr %{{.*}}, i32 %[[IDXHI]]
|
||||
// ARM: %[[IDX8:[^ ]*]] = trunc i32 %{{.*}} to i8
|
||||
// ARM: %[[IDXLO:[^ ]*]] = and i8 %[[IDX8]], 7
|
||||
// ARM: %[[MASK:[^ ]*]] = shl i8 1, %[[IDXLO]]
|
||||
// ARM: %[[BYTE:[^ ]*]] = load i8, i8* %[[BYTEADDR]], align 1
|
||||
// ARM: %[[BYTE:[^ ]*]] = load i8, ptr %[[BYTEADDR]], align 1
|
||||
// ARM: %[[NEWBYTE:[^ ]*]] = xor i8 %[[BYTE]], %[[MASK]]
|
||||
// ARM: store i8 %[[NEWBYTE]], i8* %[[BYTEADDR]], align 1
|
||||
// ARM: store i8 %[[NEWBYTE]], ptr %[[BYTEADDR]], align 1
|
||||
// ARM: %[[BYTESHR:[^ ]*]] = lshr i8 %[[BYTE]], %[[IDXLO]]
|
||||
// ARM: %[[RES:[^ ]*]] = and i8 %[[BYTESHR]], 1
|
||||
// ARM: store volatile i8 %[[RES]], i8* @sink, align 1
|
||||
// ARM: store volatile i8 %[[RES]], ptr @sink, align 1
|
||||
|
||||
// ARM: %[[IDXHI:[^ ]*]] = ashr i32 %{{.*}}, 3
|
||||
// ARM: %[[BASE:[^ ]*]] = bitcast i32* %{{.*}} to i8*
|
||||
// ARM: %[[BYTEADDR:[^ ]*]] = getelementptr inbounds i8, i8* %[[BASE]], i32 %[[IDXHI]]
|
||||
// ARM: %[[BYTEADDR:[^ ]*]] = getelementptr inbounds i8, ptr %{{.*}}, i32 %[[IDXHI]]
|
||||
// ARM: %[[IDX8:[^ ]*]] = trunc i32 %{{.*}} to i8
|
||||
// ARM: %[[IDXLO:[^ ]*]] = and i8 %[[IDX8]], 7
|
||||
// ARM: %[[MASK:[^ ]*]] = shl i8 1, %[[IDXLO]]
|
||||
// ARM: %[[BYTE:[^ ]*]] = load i8, i8* %[[BYTEADDR]], align 1
|
||||
// ARM: %[[BYTE:[^ ]*]] = load i8, ptr %[[BYTEADDR]], align 1
|
||||
// ARM: %[[NOTMASK:[^ ]*]] = xor i8 %[[MASK]], -1
|
||||
// ARM: %[[NEWBYTE:[^ ]*]] = and i8 %[[BYTE]], %[[NOTMASK]]
|
||||
// ARM: store i8 %[[NEWBYTE]], i8* %[[BYTEADDR]], align 1
|
||||
// ARM: store i8 %[[NEWBYTE]], ptr %[[BYTEADDR]], align 1
|
||||
// ARM: %[[BYTESHR:[^ ]*]] = lshr i8 %[[BYTE]], %[[IDXLO]]
|
||||
// ARM: %[[RES:[^ ]*]] = and i8 %[[BYTESHR]], 1
|
||||
// ARM: store volatile i8 %[[RES]], i8* @sink, align 1
|
||||
// ARM: store volatile i8 %[[RES]], ptr @sink, align 1
|
||||
|
||||
// ARM: %[[IDXHI:[^ ]*]] = ashr i32 %{{.*}}, 3
|
||||
// ARM: %[[BASE:[^ ]*]] = bitcast i32* %{{.*}} to i8*
|
||||
// ARM: %[[BYTEADDR:[^ ]*]] = getelementptr inbounds i8, i8* %[[BASE]], i32 %[[IDXHI]]
|
||||
// ARM: %[[BYTEADDR:[^ ]*]] = getelementptr inbounds i8, ptr %{{.*}}, i32 %[[IDXHI]]
|
||||
// ARM: %[[IDX8:[^ ]*]] = trunc i32 %{{.*}} to i8
|
||||
// ARM: %[[IDXLO:[^ ]*]] = and i8 %[[IDX8]], 7
|
||||
// ARM: %[[MASK:[^ ]*]] = shl i8 1, %[[IDXLO]]
|
||||
// ARM: %[[BYTE:[^ ]*]] = load i8, i8* %[[BYTEADDR]], align 1
|
||||
// ARM: %[[BYTE:[^ ]*]] = load i8, ptr %[[BYTEADDR]], align 1
|
||||
// ARM: %[[NEWBYTE:[^ ]*]] = or i8 %[[BYTE]], %[[MASK]]
|
||||
// ARM: store i8 %[[NEWBYTE]], i8* %[[BYTEADDR]], align 1
|
||||
// ARM: store i8 %[[NEWBYTE]], ptr %[[BYTEADDR]], align 1
|
||||
// ARM: %[[BYTESHR:[^ ]*]] = lshr i8 %[[BYTE]], %[[IDXLO]]
|
||||
// ARM: %[[RES:[^ ]*]] = and i8 %[[BYTESHR]], 1
|
||||
// ARM: store volatile i8 %[[RES]], i8* @sink, align 1
|
||||
// ARM: store volatile i8 %[[RES]], ptr @sink, align 1
|
||||
|
||||
// ARM: %[[IDXHI:[^ ]*]] = ashr i32 %{{.*}}, 3
|
||||
// ARM: %[[BASE:[^ ]*]] = bitcast i32* %{{.*}} to i8*
|
||||
// ARM: %[[BYTEADDR:[^ ]*]] = getelementptr inbounds i8, i8* %[[BASE]], i32 %[[IDXHI]]
|
||||
// ARM: %[[BYTEADDR:[^ ]*]] = getelementptr inbounds i8, ptr %{{.*}}, i32 %[[IDXHI]]
|
||||
// ARM: %[[IDX8:[^ ]*]] = trunc i32 %{{.*}} to i8
|
||||
// ARM: %[[IDXLO:[^ ]*]] = and i8 %[[IDX8]], 7
|
||||
// ARM: %[[MASK:[^ ]*]] = shl i8 1, %[[IDXLO]]
|
||||
// ARM: %[[NOTMASK:[^ ]*]] = xor i8 %[[MASK]], -1
|
||||
// ARM: %[[BYTE:[^ ]*]] = atomicrmw and i8* %[[BYTEADDR]], i8 %[[NOTMASK]] seq_cst, align 1
|
||||
// ARM: %[[BYTE:[^ ]*]] = atomicrmw and ptr %[[BYTEADDR]], i8 %[[NOTMASK]] seq_cst, align 1
|
||||
// ARM: %[[BYTESHR:[^ ]*]] = lshr i8 %[[BYTE]], %[[IDXLO]]
|
||||
// ARM: %[[RES:[^ ]*]] = and i8 %[[BYTESHR]], 1
|
||||
// ARM: store volatile i8 %[[RES]], i8* @sink, align 1
|
||||
// ARM: store volatile i8 %[[RES]], ptr @sink, align 1
|
||||
|
||||
// ARM: %[[IDXHI:[^ ]*]] = ashr i32 %{{.*}}, 3
|
||||
// ARM: %[[BASE:[^ ]*]] = bitcast i32* %{{.*}} to i8*
|
||||
// ARM: %[[BYTEADDR:[^ ]*]] = getelementptr inbounds i8, i8* %[[BASE]], i32 %[[IDXHI]]
|
||||
// ARM: %[[BYTEADDR:[^ ]*]] = getelementptr inbounds i8, ptr %{{.*}}, i32 %[[IDXHI]]
|
||||
// ARM: %[[IDX8:[^ ]*]] = trunc i32 %{{.*}} to i8
|
||||
// ARM: %[[IDXLO:[^ ]*]] = and i8 %[[IDX8]], 7
|
||||
// ARM: %[[MASK:[^ ]*]] = shl i8 1, %[[IDXLO]]
|
||||
// ARM: %[[BYTE:[^ ]*]] = atomicrmw or i8* %[[BYTEADDR]], i8 %[[MASK]] seq_cst, align 1
|
||||
// ARM: %[[BYTE:[^ ]*]] = atomicrmw or ptr %[[BYTEADDR]], i8 %[[MASK]] seq_cst, align 1
|
||||
// ARM: %[[BYTESHR:[^ ]*]] = lshr i8 %[[BYTE]], %[[IDXLO]]
|
||||
// ARM: %[[RES:[^ ]*]] = and i8 %[[BYTESHR]], 1
|
||||
// ARM: store volatile i8 %[[RES]], i8* @sink, align 1
|
||||
// ARM: store volatile i8 %[[RES]], ptr @sink, align 1
|
||||
|
||||
|
||||
// Just look for the atomicrmw instructions.
|
||||
|
||||
// ARM-LABEL: define dso_local {{.*}}void @test_arm(i32* noundef %base, i32 noundef %idx)
|
||||
// ARM: atomicrmw and i8* %{{.*}}, i8 {{.*}} acquire, align 1
|
||||
// ARM: atomicrmw and i8* %{{.*}}, i8 {{.*}} release, align 1
|
||||
// ARM: atomicrmw and i8* %{{.*}}, i8 {{.*}} monotonic, align 1
|
||||
// ARM: atomicrmw or i8* %{{.*}}, i8 {{.*}} acquire, align 1
|
||||
// ARM: atomicrmw or i8* %{{.*}}, i8 {{.*}} release, align 1
|
||||
// ARM: atomicrmw or i8* %{{.*}}, i8 {{.*}} monotonic, align 1
|
||||
// ARM-LABEL: define dso_local {{.*}}void @test_arm(ptr noundef %base, i32 noundef %idx)
|
||||
// ARM: atomicrmw and ptr %{{.*}}, i8 {{.*}} acquire, align 1
|
||||
// ARM: atomicrmw and ptr %{{.*}}, i8 {{.*}} release, align 1
|
||||
// ARM: atomicrmw and ptr %{{.*}}, i8 {{.*}} monotonic, align 1
|
||||
// ARM: atomicrmw or ptr %{{.*}}, i8 {{.*}} acquire, align 1
|
||||
// ARM: atomicrmw or ptr %{{.*}}, i8 {{.*}} release, align 1
|
||||
// ARM: atomicrmw or ptr %{{.*}}, i8 {{.*}} monotonic, align 1
|
||||
|
@ -1,4 +1,4 @@
|
||||
// RUN: %clang_cc1 -no-opaque-pointers -triple sparcv9-unknown-unknown -emit-llvm %s -o - | FileCheck %s
|
||||
// RUN: %clang_cc1 -triple sparcv9-unknown-unknown -emit-llvm %s -o - | FileCheck %s
|
||||
#include <stdarg.h>
|
||||
|
||||
// CHECK-LABEL: define{{.*}} void @f_void()
|
||||
@ -26,7 +26,7 @@ struct small {
|
||||
int *a, *b;
|
||||
};
|
||||
|
||||
// CHECK-LABEL: define{{.*}} %struct.small @f_small(i32* %x.coerce0, i32* %x.coerce1)
|
||||
// CHECK-LABEL: define{{.*}} %struct.small @f_small(ptr %x.coerce0, ptr %x.coerce1)
|
||||
struct small f_small(struct small x) {
|
||||
x.a += *x.b;
|
||||
x.b = 0;
|
||||
@ -39,7 +39,7 @@ struct medium {
|
||||
int *c, *d;
|
||||
};
|
||||
|
||||
// CHECK-LABEL: define{{.*}} %struct.medium @f_medium(%struct.medium* noundef %x)
|
||||
// CHECK-LABEL: define{{.*}} %struct.medium @f_medium(ptr noundef %x)
|
||||
struct medium f_medium(struct medium x) {
|
||||
x.a += *x.b;
|
||||
x.b = 0;
|
||||
@ -53,7 +53,7 @@ struct large {
|
||||
int x;
|
||||
};
|
||||
|
||||
// CHECK-LABEL: define{{.*}} void @f_large(%struct.large* noalias sret(%struct.large) align 8 %agg.result, %struct.large* noundef %x)
|
||||
// CHECK-LABEL: define{{.*}} void @f_large(ptr noalias sret(%struct.large) align 8 %agg.result, ptr noundef %x)
|
||||
struct large f_large(struct large x) {
|
||||
x.a += *x.b;
|
||||
x.b = 0;
|
||||
@ -120,8 +120,8 @@ void call_tiny(void) {
|
||||
f_tiny(x);
|
||||
}
|
||||
|
||||
// CHECK-LABEL: define{{.*}} signext i32 @f_variable(i8* noundef %f, ...)
|
||||
// CHECK: %ap = alloca i8*
|
||||
// CHECK-LABEL: define{{.*}} signext i32 @f_variable(ptr noundef %f, ...)
|
||||
// CHECK: %ap = alloca ptr
|
||||
// CHECK: call void @llvm.va_start
|
||||
//
|
||||
int f_variable(char *f, ...) {
|
||||
@ -131,50 +131,45 @@ int f_variable(char *f, ...) {
|
||||
va_start(ap, f);
|
||||
while ((c = *f++)) switch (c) {
|
||||
|
||||
// CHECK: %[[CUR:[^ ]+]] = load i8*, i8** %ap
|
||||
// CHECK-DAG: %[[NXT:[^ ]+]] = getelementptr inbounds i8, i8* %[[CUR]], i64 8
|
||||
// CHECK-DAG: store i8* %[[NXT]], i8** %ap
|
||||
// CHECK-DAG: %[[EXT:[^ ]+]] = getelementptr inbounds i8, i8* %[[CUR]], i64 4
|
||||
// CHECK-DAG: %[[ADR:[^ ]+]] = bitcast i8* %[[EXT]] to i32*
|
||||
// CHECK-DAG: load i32, i32* %[[ADR]]
|
||||
// CHECK: %[[CUR:[^ ]+]] = load ptr, ptr %ap
|
||||
// CHECK-DAG: %[[NXT:[^ ]+]] = getelementptr inbounds i8, ptr %[[CUR]], i64 8
|
||||
// CHECK-DAG: store ptr %[[NXT]], ptr %ap
|
||||
// CHECK-DAG: %[[EXT:[^ ]+]] = getelementptr inbounds i8, ptr %[[CUR]], i64 4
|
||||
// CHECK-DAG: load i32, ptr %[[EXT]]
|
||||
// CHECK: br
|
||||
case 'i':
|
||||
s += va_arg(ap, int);
|
||||
break;
|
||||
|
||||
// CHECK: %[[CUR:[^ ]+]] = load i8*, i8** %ap
|
||||
// CHECK-DAG: %[[NXT:[^ ]+]] = getelementptr inbounds i8, i8* %[[CUR]], i64 8
|
||||
// CHECK-DAG: store i8* %[[NXT]], i8** %ap
|
||||
// CHECK-DAG: %[[ADR:[^ ]+]] = bitcast i8* %[[CUR]] to i64*
|
||||
// CHECK-DAG: load i64, i64* %[[ADR]]
|
||||
// CHECK: %[[CUR:[^ ]+]] = load ptr, ptr %ap
|
||||
// CHECK-DAG: %[[NXT:[^ ]+]] = getelementptr inbounds i8, ptr %[[CUR]], i64 8
|
||||
// CHECK-DAG: store ptr %[[NXT]], ptr %ap
|
||||
// CHECK-DAG: load i64, ptr %[[CUR]]
|
||||
// CHECK: br
|
||||
case 'l':
|
||||
s += va_arg(ap, long);
|
||||
break;
|
||||
|
||||
// CHECK: %[[CUR:[^ ]+]] = load i8*, i8** %ap
|
||||
// CHECK-DAG: %[[NXT:[^ ]+]] = getelementptr inbounds i8, i8* %[[CUR]], i64 8
|
||||
// CHECK-DAG: store i8* %[[NXT]], i8** %ap
|
||||
// CHECK-DAG: %[[ADR:[^ ]+]] = bitcast i8* %[[CUR]] to %struct.tiny*
|
||||
// CHECK: %[[CUR:[^ ]+]] = load ptr, ptr %ap
|
||||
// CHECK-DAG: %[[NXT:[^ ]+]] = getelementptr inbounds i8, ptr %[[CUR]], i64 8
|
||||
// CHECK-DAG: store ptr %[[NXT]], ptr %ap
|
||||
// CHECK: br
|
||||
case 't':
|
||||
s += va_arg(ap, struct tiny).a;
|
||||
break;
|
||||
|
||||
// CHECK: %[[CUR:[^ ]+]] = load i8*, i8** %ap
|
||||
// CHECK-DAG: %[[NXT:[^ ]+]] = getelementptr inbounds i8, i8* %[[CUR]], i64 16
|
||||
// CHECK-DAG: store i8* %[[NXT]], i8** %ap
|
||||
// CHECK-DAG: %[[ADR:[^ ]+]] = bitcast i8* %[[CUR]] to %struct.small*
|
||||
// CHECK: %[[CUR:[^ ]+]] = load ptr, ptr %ap
|
||||
// CHECK-DAG: %[[NXT:[^ ]+]] = getelementptr inbounds i8, ptr %[[CUR]], i64 16
|
||||
// CHECK-DAG: store ptr %[[NXT]], ptr %ap
|
||||
// CHECK: br
|
||||
case 's':
|
||||
s += *va_arg(ap, struct small).a;
|
||||
break;
|
||||
|
||||
// CHECK: %[[CUR:[^ ]+]] = load i8*, i8** %ap
|
||||
// CHECK-DAG: %[[NXT:[^ ]+]] = getelementptr inbounds i8, i8* %[[CUR]], i64 8
|
||||
// CHECK-DAG: store i8* %[[NXT]], i8** %ap
|
||||
// CHECK-DAG: %[[IND:[^ ]+]] = bitcast i8* %[[CUR]] to %struct.medium**
|
||||
// CHECK-DAG: %[[ADR:[^ ]+]] = load %struct.medium*, %struct.medium** %[[IND]]
|
||||
// CHECK: %[[CUR:[^ ]+]] = load ptr, ptr %ap
|
||||
// CHECK-DAG: %[[NXT:[^ ]+]] = getelementptr inbounds i8, ptr %[[CUR]], i64 8
|
||||
// CHECK-DAG: store ptr %[[NXT]], ptr %ap
|
||||
// CHECK-DAG: %[[ADR:[^ ]+]] = load ptr, ptr %[[CUR]]
|
||||
// CHECK: br
|
||||
case 'm':
|
||||
s += *va_arg(ap, struct medium).a;
|
||||
|
@ -1,4 +1,4 @@
|
||||
// RUN: %clang_cc1 -no-opaque-pointers -std=c++11 -fblocks -fms-extensions %s -triple=x86_64-windows-msvc -emit-llvm \
|
||||
// RUN: %clang_cc1 -std=c++11 -fblocks -fms-extensions %s -triple=x86_64-windows-msvc -emit-llvm \
|
||||
// RUN: -o - -mconstructor-aliases -fcxx-exceptions -fexceptions | FileCheck %s
|
||||
|
||||
extern "C" int basic_filter(int v, ...);
|
||||
@ -14,20 +14,18 @@ extern "C" void test_freefunc(int p1) {
|
||||
}
|
||||
|
||||
// CHECK-LABEL: define dso_local void @test_freefunc(i32 noundef %p1)
|
||||
// CHECK: @llvm.localescape(i32* %[[p1_ptr:[^, ]*]], i32* %[[l1_ptr:[^, ]*]])
|
||||
// CHECK: store i32 %p1, i32* %[[p1_ptr]], align 4
|
||||
// CHECK: store i32 13, i32* %[[l1_ptr]], align 4
|
||||
// CHECK: @llvm.localescape(ptr %[[p1_ptr:[^, ]*]], ptr %[[l1_ptr:[^, ]*]])
|
||||
// CHECK: store i32 %p1, ptr %[[p1_ptr]], align 4
|
||||
// CHECK: store i32 13, ptr %[[l1_ptr]], align 4
|
||||
// CHECK: invoke void @might_crash()
|
||||
|
||||
// CHECK-LABEL: define internal noundef i32 @"?filt$0@0@test_freefunc@@"(i8* noundef %exception_pointers, i8* noundef %frame_pointer)
|
||||
// CHECK: %[[fp:[^ ]*]] = call i8* @llvm.eh.recoverfp(i8* bitcast (void (i32)* @test_freefunc to i8*), i8* %frame_pointer)
|
||||
// CHECK: %[[p1_i8:[^ ]*]] = call i8* @llvm.localrecover(i8* bitcast (void (i32)* @test_freefunc to i8*), i8* %[[fp]], i32 0)
|
||||
// CHECK: %[[p1_ptr:[^ ]*]] = bitcast i8* %[[p1_i8]] to i32*
|
||||
// CHECK: %[[l1_i8:[^ ]*]] = call i8* @llvm.localrecover(i8* bitcast (void (i32)* @test_freefunc to i8*), i8* %[[fp]], i32 1)
|
||||
// CHECK: %[[l1_ptr:[^ ]*]] = bitcast i8* %[[l1_i8]] to i32*
|
||||
// CHECK: %[[s1:[^ ]*]] = load i32, i32* @"?s1@?1??test_freefunc@@9@4HA", align 4
|
||||
// CHECK: %[[l1:[^ ]*]] = load i32, i32* %[[l1_ptr]]
|
||||
// CHECK: %[[p1:[^ ]*]] = load i32, i32* %[[p1_ptr]]
|
||||
// CHECK-LABEL: define internal noundef i32 @"?filt$0@0@test_freefunc@@"(ptr noundef %exception_pointers, ptr noundef %frame_pointer)
|
||||
// CHECK: %[[fp:[^ ]*]] = call ptr @llvm.eh.recoverfp(ptr @test_freefunc, ptr %frame_pointer)
|
||||
// CHECK: %[[p1_i8:[^ ]*]] = call ptr @llvm.localrecover(ptr @test_freefunc, ptr %[[fp]], i32 0)
|
||||
// CHECK: %[[l1_i8:[^ ]*]] = call ptr @llvm.localrecover(ptr @test_freefunc, ptr %[[fp]], i32 1)
|
||||
// CHECK: %[[s1:[^ ]*]] = load i32, ptr @"?s1@?1??test_freefunc@@9@4HA", align 4
|
||||
// CHECK: %[[l1:[^ ]*]] = load i32, ptr %[[l1_i8]]
|
||||
// CHECK: %[[p1:[^ ]*]] = load i32, ptr %[[p1_i8]]
|
||||
// CHECK: call i32 (i32, ...) @basic_filter(i32 noundef %[[p1]], i32 noundef %[[l1]], i32 noundef %[[s1]])
|
||||
|
||||
struct S {
|
||||
@ -43,22 +41,20 @@ void S::test_method() {
|
||||
}
|
||||
}
|
||||
|
||||
// CHECK-LABEL: define dso_local void @"?test_method@S@@QEAAXXZ"(%struct.S* {{[^,]*}} %this)
|
||||
// CHECK: @llvm.localescape(i32* %[[l1_addr:[^, ]*]], %struct.S** %[[this_addr:[^, ]*]])
|
||||
// CHECK: store %struct.S* %this, %struct.S** %[[this_addr]], align 8
|
||||
// CHECK: store i32 13, i32* %[[l1_addr]], align 4
|
||||
// CHECK-LABEL: define dso_local void @"?test_method@S@@QEAAXXZ"(ptr {{[^,]*}} %this)
|
||||
// CHECK: @llvm.localescape(ptr %[[l1_addr:[^, ]*]], ptr %[[this_addr:[^, ]*]])
|
||||
// CHECK: store ptr %this, ptr %[[this_addr]], align 8
|
||||
// CHECK: store i32 13, ptr %[[l1_addr]], align 4
|
||||
// CHECK: invoke void @might_crash()
|
||||
|
||||
// CHECK-LABEL: define internal noundef i32 @"?filt$0@0@test_method@S@@"(i8* noundef %exception_pointers, i8* noundef %frame_pointer)
|
||||
// CHECK: %[[fp:[^ ]*]] = call i8* @llvm.eh.recoverfp(i8* bitcast (void (%struct.S*)* @"?test_method@S@@QEAAXXZ" to i8*), i8* %frame_pointer)
|
||||
// CHECK: %[[l1_i8:[^ ]*]] = call i8* @llvm.localrecover(i8* bitcast (void (%struct.S*)* @"?test_method@S@@QEAAXXZ" to i8*), i8* %[[fp]], i32 0)
|
||||
// CHECK: %[[l1_ptr:[^ ]*]] = bitcast i8* %[[l1_i8]] to i32*
|
||||
// CHECK: %[[this_i8:[^ ]*]] = call i8* @llvm.localrecover(i8* bitcast (void (%struct.S*)* @"?test_method@S@@QEAAXXZ" to i8*), i8* %[[fp]], i32 1)
|
||||
// CHECK: %[[this_ptr:[^ ]*]] = bitcast i8* %[[this_i8]] to %struct.S**
|
||||
// CHECK: %[[this:[^ ]*]] = load %struct.S*, %struct.S** %[[this_ptr]], align 8
|
||||
// CHECK: %[[m1_ptr:[^ ]*]] = getelementptr inbounds %struct.S, %struct.S* %[[this]], i32 0, i32 0
|
||||
// CHECK: %[[m1:[^ ]*]] = load i32, i32* %[[m1_ptr]]
|
||||
// CHECK: %[[l1:[^ ]*]] = load i32, i32* %[[l1_ptr]]
|
||||
// CHECK-LABEL: define internal noundef i32 @"?filt$0@0@test_method@S@@"(ptr noundef %exception_pointers, ptr noundef %frame_pointer)
|
||||
// CHECK: %[[fp:[^ ]*]] = call ptr @llvm.eh.recoverfp(ptr @"?test_method@S@@QEAAXXZ", ptr %frame_pointer)
|
||||
// CHECK: %[[l1_i8:[^ ]*]] = call ptr @llvm.localrecover(ptr @"?test_method@S@@QEAAXXZ", ptr %[[fp]], i32 0)
|
||||
// CHECK: %[[this_i8:[^ ]*]] = call ptr @llvm.localrecover(ptr @"?test_method@S@@QEAAXXZ", ptr %[[fp]], i32 1)
|
||||
// CHECK: %[[this:[^ ]*]] = load ptr, ptr %[[this_i8]], align 8
|
||||
// CHECK: %[[m1_ptr:[^ ]*]] = getelementptr inbounds %struct.S, ptr %[[this]], i32 0, i32 0
|
||||
// CHECK: %[[m1:[^ ]*]] = load i32, ptr %[[m1_ptr]]
|
||||
// CHECK: %[[l1:[^ ]*]] = load i32, ptr %[[l1_i8]]
|
||||
// CHECK: call i32 (i32, ...) @basic_filter(i32 noundef %[[l1]], i32 noundef %[[m1]])
|
||||
|
||||
struct V {
|
||||
@ -74,24 +70,21 @@ void V::test_virtual(int p1) {
|
||||
}
|
||||
}
|
||||
|
||||
// CHECK-LABEL: define dso_local void @"?test_virtual@V@@QEAAXH@Z"(%struct.V* {{[^,]*}} %this, i32 noundef %p1)
|
||||
// CHECK: @llvm.localescape(%struct.V** %[[this_addr:[^, ]*]], i32* %[[p1_addr:[^, ]*]])
|
||||
// CHECK: store i32 %p1, i32* %[[p1_addr]], align 4
|
||||
// CHECK: store %struct.V* %this, %struct.V** %[[this_addr]], align 8
|
||||
// CHECK-LABEL: define dso_local void @"?test_virtual@V@@QEAAXH@Z"(ptr {{[^,]*}} %this, i32 noundef %p1)
|
||||
// CHECK: @llvm.localescape(ptr %[[this_addr:[^, ]*]], ptr %[[p1_addr:[^, ]*]])
|
||||
// CHECK: store i32 %p1, ptr %[[p1_addr]], align 4
|
||||
// CHECK: store ptr %this, ptr %[[this_addr]], align 8
|
||||
// CHECK: invoke void @might_crash()
|
||||
|
||||
// CHECK-LABEL: define internal void @"?fin$0@0@test_virtual@V@@"(i8 noundef %abnormal_termination, i8* noundef %frame_pointer)
|
||||
// CHECK: %[[this_i8:[^ ]*]] = call i8* @llvm.localrecover(i8* bitcast (void (%struct.V*, i32)* @"?test_virtual@V@@QEAAXH@Z" to i8*), i8* %frame_pointer, i32 0)
|
||||
// CHECK: %[[this_ptr:[^ ]*]] = bitcast i8* %[[this_i8]] to %struct.V**
|
||||
// CHECK: %[[this:[^ ]*]] = load %struct.V*, %struct.V** %[[this_ptr]], align 8
|
||||
// CHECK: %[[p1_i8:[^ ]*]] = call i8* @llvm.localrecover(i8* bitcast (void (%struct.V*, i32)* @"?test_virtual@V@@QEAAXH@Z" to i8*), i8* %frame_pointer, i32 1)
|
||||
// CHECK: %[[p1_ptr:[^ ]*]] = bitcast i8* %[[p1_i8]] to i32*
|
||||
// CHECK: %[[p1:[^ ]*]] = load i32, i32* %[[p1_ptr]]
|
||||
// CHECK: %[[this_2:[^ ]*]] = bitcast %struct.V* %[[this]] to void (%struct.V*, i32)***
|
||||
// CHECK: %[[vtable:[^ ]*]] = load void (%struct.V*, i32)**, void (%struct.V*, i32)*** %[[this_2]], align 8
|
||||
// CHECK: %[[vfn:[^ ]*]] = getelementptr inbounds void (%struct.V*, i32)*, void (%struct.V*, i32)** %[[vtable]], i64 0
|
||||
// CHECK: %[[virt:[^ ]*]] = load void (%struct.V*, i32)*, void (%struct.V*, i32)** %[[vfn]], align 8
|
||||
// CHECK: call void %[[virt]](%struct.V* {{[^,]*}} %[[this]], i32 noundef %[[p1]])
|
||||
// CHECK-LABEL: define internal void @"?fin$0@0@test_virtual@V@@"(i8 noundef %abnormal_termination, ptr noundef %frame_pointer)
|
||||
// CHECK: %[[this_i8:[^ ]*]] = call ptr @llvm.localrecover(ptr @"?test_virtual@V@@QEAAXH@Z", ptr %frame_pointer, i32 0)
|
||||
// CHECK: %[[this:[^ ]*]] = load ptr, ptr %[[this_i8]], align 8
|
||||
// CHECK: %[[p1_i8:[^ ]*]] = call ptr @llvm.localrecover(ptr @"?test_virtual@V@@QEAAXH@Z", ptr %frame_pointer, i32 1)
|
||||
// CHECK: %[[p1:[^ ]*]] = load i32, ptr %[[p1_i8]]
|
||||
// CHECK: %[[vtable:[^ ]*]] = load ptr, ptr %[[this]], align 8
|
||||
// CHECK: %[[vfn:[^ ]*]] = getelementptr inbounds ptr, ptr %[[vtable]], i64 0
|
||||
// CHECK: %[[virt:[^ ]*]] = load ptr, ptr %[[vfn]], align 8
|
||||
// CHECK: call void %[[virt]](ptr {{[^,]*}} %[[this]], i32 noundef %[[p1]])
|
||||
|
||||
void test_lambda() {
|
||||
int l1 = 13;
|
||||
@ -105,23 +98,21 @@ void test_lambda() {
|
||||
lambda();
|
||||
}
|
||||
|
||||
// CHECK-LABEL: define internal void @"??R<lambda_0>@?0??test_lambda@@YAXXZ@QEBA@XZ"(%class.anon* {{[^,]*}} %this)
|
||||
// CHECK: @llvm.localescape(%class.anon** %[[this_addr:[^, ]*]], i32* %[[l2_addr:[^, ]*]])
|
||||
// CHECK: store %class.anon* %this, %class.anon** %[[this_addr]], align 8
|
||||
// CHECK: store i32 42, i32* %[[l2_addr]], align 4
|
||||
// CHECK-LABEL: define internal void @"??R<lambda_0>@?0??test_lambda@@YAXXZ@QEBA@XZ"(ptr {{[^,]*}} %this)
|
||||
// CHECK: @llvm.localescape(ptr %[[this_addr:[^, ]*]], ptr %[[l2_addr:[^, ]*]])
|
||||
// CHECK: store ptr %this, ptr %[[this_addr]], align 8
|
||||
// CHECK: store i32 42, ptr %[[l2_addr]], align 4
|
||||
// CHECK: invoke void @might_crash()
|
||||
|
||||
// CHECK-LABEL: define internal noundef i32 @"?filt$0@0@?R<lambda_0>@?0??test_lambda@@YAXXZ@"(i8* noundef %exception_pointers, i8* noundef %frame_pointer)
|
||||
// CHECK: %[[fp:[^ ]*]] = call i8* @llvm.eh.recoverfp(i8* bitcast (void (%class.anon*)* @"??R<lambda_0>@?0??test_lambda@@YAXXZ@QEBA@XZ" to i8*), i8* %frame_pointer)
|
||||
// CHECK: %[[this_i8:[^ ]*]] = call i8* @llvm.localrecover(i8* bitcast (void (%class.anon*)* @"??R<lambda_0>@?0??test_lambda@@YAXXZ@QEBA@XZ" to i8*), i8* %[[fp]], i32 0)
|
||||
// CHECK: %[[this_ptr:[^ ]*]] = bitcast i8* %[[this_i8]] to %class.anon**
|
||||
// CHECK: %[[this:[^ ]*]] = load %class.anon*, %class.anon** %[[this_ptr]], align 8
|
||||
// CHECK: %[[l2_i8:[^ ]*]] = call i8* @llvm.localrecover(i8* bitcast (void (%class.anon*)* @"??R<lambda_0>@?0??test_lambda@@YAXXZ@QEBA@XZ" to i8*), i8* %[[fp]], i32 1)
|
||||
// CHECK: %[[l2_ptr:[^ ]*]] = bitcast i8* %[[l2_i8]] to i32*
|
||||
// CHECK: %[[l2:[^ ]*]] = load i32, i32* %[[l2_ptr]]
|
||||
// CHECK: %[[l1_ref_ptr:[^ ]*]] = getelementptr inbounds %class.anon, %class.anon* %[[this]], i32 0, i32 0
|
||||
// CHECK: %[[l1_ref:[^ ]*]] = load i32*, i32** %[[l1_ref_ptr]]
|
||||
// CHECK: %[[l1:[^ ]*]] = load i32, i32* %[[l1_ref]]
|
||||
// CHECK-LABEL: define internal noundef i32 @"?filt$0@0@?R<lambda_0>@?0??test_lambda@@YAXXZ@"(ptr noundef %exception_pointers, ptr noundef %frame_pointer)
|
||||
// CHECK: %[[fp:[^ ]*]] = call ptr @llvm.eh.recoverfp(ptr @"??R<lambda_0>@?0??test_lambda@@YAXXZ@QEBA@XZ", ptr %frame_pointer)
|
||||
// CHECK: %[[this_i8:[^ ]*]] = call ptr @llvm.localrecover(ptr @"??R<lambda_0>@?0??test_lambda@@YAXXZ@QEBA@XZ", ptr %[[fp]], i32 0)
|
||||
// CHECK: %[[this:[^ ]*]] = load ptr, ptr %[[this_i8]], align 8
|
||||
// CHECK: %[[l2_i8:[^ ]*]] = call ptr @llvm.localrecover(ptr @"??R<lambda_0>@?0??test_lambda@@YAXXZ@QEBA@XZ", ptr %[[fp]], i32 1)
|
||||
// CHECK: %[[l2:[^ ]*]] = load i32, ptr %[[l2_i8]]
|
||||
// CHECK: %[[l1_ref_ptr:[^ ]*]] = getelementptr inbounds %class.anon, ptr %[[this]], i32 0, i32 0
|
||||
// CHECK: %[[l1_ref:[^ ]*]] = load ptr, ptr %[[l1_ref_ptr]]
|
||||
// CHECK: %[[l1:[^ ]*]] = load i32, ptr %[[l1_ref]]
|
||||
// CHECK: call i32 (i32, ...) @basic_filter(i32 noundef %[[l1]], i32 noundef %[[l2]])
|
||||
|
||||
struct U {
|
||||
@ -138,10 +129,9 @@ void U::this_in_lambda() {
|
||||
lambda();
|
||||
}
|
||||
|
||||
// CHECK-LABEL: define internal noundef i32 @"?filt$0@0@?R<lambda_1>@?0??this_in_lambda@U@@QEAAXXZ@"(i8* noundef %exception_pointers, i8* noundef %frame_pointer)
|
||||
// CHECK: %[[this_i8:[^ ]*]] = call i8* @llvm.localrecover(i8* bitcast (void (%class.anon.0*)* @"??R<lambda_1>@?0??this_in_lambda@U@@QEAAXXZ@QEBA@XZ" to i8*), i8* %[[fp:[^ ]*]], i32 0)
|
||||
// CHECK: %[[this_ptr:[^ ]*]] = bitcast i8* %[[this_i8]] to %class.anon.0**
|
||||
// CHECK: %[[this:[^ ]*]] = load %class.anon.0*, %class.anon.0** %[[this_ptr]], align 8
|
||||
// CHECK: %[[actual_this_ptr:[^ ]*]] = getelementptr inbounds %class.anon.0, %class.anon.0* %[[this]], i32 0, i32 0
|
||||
// CHECK: %[[actual_this:[^ ]*]] = load %struct.U*, %struct.U** %[[actual_this_ptr]], align 8
|
||||
// CHECK: call i32 (i32, ...) @basic_filter(i32 noundef 0, %struct.U* noundef %[[actual_this]])
|
||||
// CHECK-LABEL: define internal noundef i32 @"?filt$0@0@?R<lambda_1>@?0??this_in_lambda@U@@QEAAXXZ@"(ptr noundef %exception_pointers, ptr noundef %frame_pointer)
|
||||
// CHECK: %[[this_i8:[^ ]*]] = call ptr @llvm.localrecover(ptr @"??R<lambda_1>@?0??this_in_lambda@U@@QEAAXXZ@QEBA@XZ", ptr %[[fp:[^ ]*]], i32 0)
|
||||
// CHECK: %[[this:[^ ]*]] = load ptr, ptr %[[this_i8]], align 8
|
||||
// CHECK: %[[actual_this_ptr:[^ ]*]] = getelementptr inbounds %class.anon.0, ptr %[[this]], i32 0, i32 0
|
||||
// CHECK: %[[actual_this:[^ ]*]] = load ptr, ptr %[[actual_this_ptr]], align 8
|
||||
// CHECK: call i32 (i32, ...) @basic_filter(i32 noundef 0, ptr noundef %[[actual_this]])
|
||||
|
@ -1,4 +1,4 @@
|
||||
// RUN: %clang_cc1 -no-opaque-pointers %s -fno-rtti -triple=i386-pc-win32 -emit-llvm -o %t.ll -fdump-vtable-layouts >%t
|
||||
// RUN: %clang_cc1 %s -fno-rtti -triple=i386-pc-win32 -emit-llvm -o %t.ll -fdump-vtable-layouts >%t
|
||||
// RUN: FileCheck %s < %t
|
||||
// RUN: FileCheck --check-prefix=BITCODE %s < %t.ll
|
||||
|
||||
@ -156,17 +156,15 @@ struct C : public A, public B {
|
||||
|
||||
// BITCODE-LABEL: define {{.*}}"?ffun@test4@@YAXAAUC@1@@Z
|
||||
void ffun(C &c) {
|
||||
// BITCODE: [[THIS1:%.+]] = bitcast %"struct.test4::C"* {{.*}} to i8*
|
||||
// BITCODE: [[THIS2:%.+]] = getelementptr inbounds i8, i8* [[THIS1]], i32 4
|
||||
// BITCODE: call x86_thiscallcc {{.*}}(i8* noundef [[THIS2]])
|
||||
// BITCODE: [[THIS2:%.+]] = getelementptr inbounds i8, ptr {{.*}}, i32 4
|
||||
// BITCODE: call x86_thiscallcc {{.*}}(ptr noundef [[THIS2]])
|
||||
c.bar();
|
||||
}
|
||||
|
||||
// BITCODE-LABEL: define {{.*}}"?fop@test4@@YAXAAUC@1@@Z
|
||||
void fop(C &c) {
|
||||
// BITCODE: [[THIS1:%.+]] = bitcast %"struct.test4::C"* {{.*}} to i8*
|
||||
// BITCODE: [[THIS2:%.+]] = getelementptr inbounds i8, i8* [[THIS1]], i32 4
|
||||
// BITCODE: call x86_thiscallcc {{.*}}(i8* noundef [[THIS2]])
|
||||
// BITCODE: [[THIS2:%.+]] = getelementptr inbounds i8, ptr {{.*}}, i32 4
|
||||
// BITCODE: call x86_thiscallcc {{.*}}(ptr noundef [[THIS2]])
|
||||
-c;
|
||||
}
|
||||
|
||||
@ -189,12 +187,9 @@ void C::g(NonTrivial o) {
|
||||
whatsthis = this;
|
||||
}
|
||||
|
||||
// BITCODE-LABEL: define dso_local void @"?g@C@pr30293@@UAAXUNonTrivial@2@@Z"(<{ i8*, %"struct.pr30293::NonTrivial" }>* inalloca(<{ i8*, %"struct.pr30293::NonTrivial" }>) %0)
|
||||
// BITCODE: %[[thisaddr:[^ ]*]] = getelementptr inbounds <{ i8*, %"struct.pr30293::NonTrivial" }>, <{ i8*, %"struct.pr30293::NonTrivial" }>* {{.*}}, i32 0, i32 0
|
||||
// BITCODE: %[[thisaddr1:[^ ]*]] = bitcast i8** %[[thisaddr]] to %"struct.pr30293::C"**
|
||||
// BITCODE: %[[this1:[^ ]*]] = load %"struct.pr30293::C"*, %"struct.pr30293::C"** %[[thisaddr1]], align 4
|
||||
// BITCODE: %[[this2:[^ ]*]] = bitcast %"struct.pr30293::C"* %[[this1]] to i8*
|
||||
// BITCODE: %[[this3:[^ ]*]] = getelementptr inbounds i8, i8* %[[this2]], i32 -4
|
||||
// BITCODE: %[[this4:[^ ]*]] = bitcast i8* %[[this3]] to %"struct.pr30293::C"*
|
||||
// BITCODE: store %"struct.pr30293::C"* %[[this4]], %"struct.pr30293::C"** @"?whatsthis@pr30293@@3PAUC@1@A", align 4
|
||||
// BITCODE-LABEL: define dso_local void @"?g@C@pr30293@@UAAXUNonTrivial@2@@Z"(ptr inalloca(<{ ptr, %"struct.pr30293::NonTrivial" }>) %0)
|
||||
// BITCODE: %[[thisaddr:[^ ]*]] = getelementptr inbounds <{ ptr, %"struct.pr30293::NonTrivial" }>, ptr {{.*}}, i32 0, i32 0
|
||||
// BITCODE: %[[this1:[^ ]*]] = load ptr, ptr %[[thisaddr]], align 4
|
||||
// BITCODE: %[[this3:[^ ]*]] = getelementptr inbounds i8, ptr %[[this1]], i32 -4
|
||||
// BITCODE: store ptr %[[this3]], ptr @"?whatsthis@pr30293@@3PAUC@1@A", align 4
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user