Skip to content

[KeyInstr][Clang] Coerced store atoms #134653

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 6 commits into
base: users/OCHyams/ki-clang-ret
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
21 changes: 13 additions & 8 deletions clang/lib/CodeGen/CGCall.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1424,24 +1424,28 @@ void CodeGenFunction::CreateCoercedStore(llvm::Value *Src, Address Dst,
SrcSize == CGM.getDataLayout().getTypeAllocSize(Dst.getElementType())) {
// If the value is supposed to be a pointer, convert it before storing it.
Src = CoerceIntOrPtrToIntOrPtr(Src, Dst.getElementType(), *this);
Builder.CreateStore(Src, Dst, DstIsVolatile);
auto *I = Builder.CreateStore(Src, Dst, DstIsVolatile);
addInstToCurrentSourceAtom(I, Src);
} else if (llvm::StructType *STy =
dyn_cast<llvm::StructType>(Src->getType())) {
// Prefer scalar stores to first-class aggregate stores.
Dst = Dst.withElementType(SrcTy);
for (unsigned i = 0, e = STy->getNumElements(); i != e; ++i) {
Address EltPtr = Builder.CreateStructGEP(Dst, i);
llvm::Value *Elt = Builder.CreateExtractValue(Src, i);
Builder.CreateStore(Elt, EltPtr, DstIsVolatile);
auto *I = Builder.CreateStore(Elt, EltPtr, DstIsVolatile);
addInstToCurrentSourceAtom(I, Elt);
}
} else {
Builder.CreateStore(Src, Dst.withElementType(SrcTy), DstIsVolatile);
auto * I = Builder.CreateStore(Src, Dst.withElementType(SrcTy), DstIsVolatile);
addInstToCurrentSourceAtom(I, Src);
}
} else if (SrcTy->isIntegerTy()) {
// If the source is a simple integer, coerce it directly.
llvm::Type *DstIntTy = Builder.getIntNTy(DstSize.getFixedValue() * 8);
Src = CoerceIntOrPtrToIntOrPtr(Src, DstIntTy, *this);
Builder.CreateStore(Src, Dst.withElementType(DstIntTy), DstIsVolatile);
auto *I = Builder.CreateStore(Src, Dst.withElementType(DstIntTy), DstIsVolatile);
addInstToCurrentSourceAtom(I, Src);
} else {
// Otherwise do coercion through memory. This is stupid, but
// simple.
Expand All @@ -1455,10 +1459,11 @@ void CodeGenFunction::CreateCoercedStore(llvm::Value *Src, Address Dst,
RawAddress Tmp =
CreateTempAllocaForCoercion(*this, SrcTy, Dst.getAlignment());
Builder.CreateStore(Src, Tmp);
Builder.CreateMemCpy(Dst.emitRawPointer(*this),
Dst.getAlignment().getAsAlign(), Tmp.getPointer(),
Tmp.getAlignment().getAsAlign(),
Builder.CreateTypeSize(IntPtrTy, DstSize));
auto *I = Builder.CreateMemCpy(
Dst.emitRawPointer(*this), Dst.getAlignment().getAsAlign(),
Tmp.getPointer(), Tmp.getAlignment().getAsAlign(),
Builder.CreateTypeSize(IntPtrTy, DstSize));
addInstToCurrentSourceAtom(I, Src);
}
}

Expand Down
22 changes: 22 additions & 0 deletions clang/test/KeyInstructions/coerced-packed.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
// RUN: %clang_cc1 -gkey-instructions -gno-column-info -x c++ %s %clang_cc1-debug-info-kind=line-tables-only -emit-llvm -o - -target arm64-apple-ios11 \
// RUN: | FileCheck %s --implicit-check-not atomGroup --implicit-check-not atomRank

// RUN: %clang_cc1 -gkey-instructions -gno-column-info -x c %s %clang_cc1-debug-info-kind=line-tables-only -emit-llvm -o - -target arm64-apple-ios11 \
// RUN: | FileCheck %s --implicit-check-not atomGroup --implicit-check-not atomRank

typedef struct {
char a;
int x;
} __attribute((packed)) S;

S getS();
void f() {
// CHECK: [[call:%.*]] = call i40{{.*}}getS{{.*}}, !dbg [[G1R2:!.*]]
// CHECK: store i40 [[call]], ptr %s, align 1, !dbg [[G1R1:!.*]]
S s = getS();
// CHECK: ret void, !dbg [[G2R1:!.*]]
}

// CHECK: [[G1R2]] = !DILocation({{.*}}, atomGroup: 1, atomRank: 2)
// CHECK: [[G1R1]] = !DILocation({{.*}}, atomGroup: 1, atomRank: 1)
// CHECK: [[G2R1]] = !DILocation({{.*}}, atomGroup: 2, atomRank: 1)
21 changes: 21 additions & 0 deletions clang/test/KeyInstructions/coerced-ptr.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
// RUN: %clang_cc1 -gkey-instructions -gno-column-info -x c++ %s %clang_cc1-debug-info-kind=line-tables-only -emit-llvm -o - -target x86_64-windows-msvc \
// RUN: | FileCheck %s --implicit-check-not atomGroup --implicit-check-not atomRank

// RUN: %clang_cc1 -gkey-instructions -gno-column-info -x c %s %clang_cc1-debug-info-kind=line-tables-only -emit-llvm -o - -target x86_64-windows-msvc \
// RUN: | FileCheck %s --implicit-check-not atomGroup --implicit-check-not atomRank

typedef struct { int *p; } Ptr;
Ptr getPtr();
void f() {
// CHECK: %call = call i64{{.*}}, !dbg [[G1R3:!.*]]
// CHECK: [[gep:%.*]] = getelementptr inbounds nuw %struct.Ptr, ptr %p, i32 0, i32 0
// CHECK: [[i2p:%.*]] = inttoptr i64 %call to ptr, !dbg [[G1R2:!.*]]
// CHECK: store ptr [[i2p]], ptr [[gep]], align 8, !dbg [[G1R1:!.*]]
Ptr p = getPtr();
// CHECK: ret void, !dbg [[G2R1:!.*]]
}

// CHECK: [[G1R3]] = !DILocation({{.*}}, atomGroup: 1, atomRank: 3)
// CHECK: [[G1R2]] = !DILocation({{.*}}, atomGroup: 1, atomRank: 2)
// CHECK: [[G1R1]] = !DILocation({{.*}}, atomGroup: 1, atomRank: 1)
// CHECK: [[G2R1]] = !DILocation({{.*}}, atomGroup: 2, atomRank: 1)
26 changes: 26 additions & 0 deletions clang/test/KeyInstructions/coerced-through-memory.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
// RUN: %clang_cc1 -gkey-instructions -gno-column-info -x c++ %s %clang_cc1-debug-info-kind=line-tables-only -emit-llvm -o - -target aarch64-windows-msvc \
// RUN: | FileCheck %s --implicit-check-not atomGroup --implicit-check-not atomRank

// RUN: %clang_cc1 -gkey-instructions -gno-column-info -x c %s %clang_cc1-debug-info-kind=line-tables-only -emit-llvm -o - -target aarch64-windows-msvc \
// RUN: | FileCheck %s --implicit-check-not atomGroup --implicit-check-not atomRank

typedef struct {
short a;
int b;
short c;
} S;

S getS(void);

void f() {
// CHECK: %call = call [2 x i64] {{.*}}getS{{.*}}(), !dbg [[G1R2:!.*]]
//// Note: The store to the tmp alloca isn't part of the atom.
// CHECK: store [2 x i64] %call, ptr %tmp.coerce, align 8
// CHECK: call void @llvm.memcpy.p0.p0.i64(ptr align 4 %s, ptr align 8 %tmp.coerce, i64 12, i1 false), !dbg [[G1R1:!.*]]
S s = getS();
// CHECK: ret void, !dbg [[G2R1:!.*]]
}

// CHECK: [[G1R2]] = !DILocation({{.*}}, atomGroup: 1, atomRank: 2)
// CHECK: [[G1R1]] = !DILocation({{.*}}, atomGroup: 1, atomRank: 1)
// CHECK: [[G2R1]] = !DILocation({{.*}}, atomGroup: 2, atomRank: 1)
40 changes: 40 additions & 0 deletions clang/test/KeyInstructions/coerced.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
// RUN: %clang_cc1 -gkey-instructions -gno-column-info -x c++ %s %clang_cc1-debug-info-kind=line-tables-only -emit-llvm -o - -target x86_64-unknown-linux \
// RUN: | FileCheck %s --implicit-check-not atomGroup --implicit-check-not atomRank --check-prefixes=CHECK,CHECK-CXX

// RUN: %clang_cc1 -gkey-instructions -gno-column-info -x c %s %clang_cc1-debug-info-kind=line-tables-only -emit-llvm -o - -target x86_64-unknown-linux \
// RUN: | FileCheck %s --implicit-check-not atomGroup --implicit-check-not atomRank --check-prefixes=CHECK,CHECK-C

typedef struct {
void* a;
void* b;
} Struct;
Struct get();

void test() {
// CHECK: %1 = extractvalue { ptr, ptr } %call, 0, !dbg [[G1R2:!.*]]
// CHECK: store ptr %1, ptr {{.*}}, !dbg [[G1R1:!.*]]
// CHECK: %3 = extractvalue { ptr, ptr } %call, 1, !dbg [[G1R2]]
// CHECK: store ptr %3, ptr {{.*}}, !dbg [[G1R1:!.*]]
Struct s = get();
// CHECK: ret void, !dbg [[G2R1:!.*]]
}

typedef struct { int i; } Int;
Int getInt(void);

// CHECK-C: @test2
// CHECK-CXX: @_Z5test2v
void test2() {
// CHECK: %call = call i32 @{{(_Z6)?}}getInt{{v?}}(), !dbg [[T2_G1R2:!.*]]
// CHECK: [[gep:%.*]] = getelementptr inbounds nuw %struct.Int, ptr %i, i32 0, i32 0
// CHECK: store i32 %call, ptr [[gep]]{{.*}}, !dbg [[T2_G1R1:!.*]]
Int i = getInt();
// CHECK: ret void, !dbg [[T2_G2R1:!.*]]
}

// CHECK: [[G1R2]] = !DILocation({{.*}}, atomGroup: 1, atomRank: 2)
// CHECK: [[G1R1]] = !DILocation({{.*}}, atomGroup: 1, atomRank: 1)
// CHECK: [[G2R1]] = !DILocation({{.*}}, atomGroup: 2, atomRank: 1)
// CHECK: [[T2_G1R2]] = !DILocation({{.*}}, atomGroup: 1, atomRank: 2)
// CHECK: [[T2_G1R1]] = !DILocation({{.*}}, atomGroup: 1, atomRank: 1)
// CHECK: [[T2_G2R1]] = !DILocation({{.*}}, atomGroup: 2, atomRank: 1)
Loading