diff --git a/clang/include/clang/Basic/Builtins.def b/clang/include/clang/Basic/Builtins.def --- a/clang/include/clang/Basic/Builtins.def +++ b/clang/include/clang/Basic/Builtins.def @@ -662,6 +662,7 @@ BUILTIN(__builtin_alloca_with_align_uninitialized, "v*zIz", "Fn") BUILTIN(__builtin_call_with_static_chain, "v.", "nt") BUILTIN(__builtin_nondeterministic_value, "v.", "nt") +BUILTIN(__builtin_implicit_object_fence, "v*v*", "n") BUILTIN(__builtin_elementwise_abs, "v.", "nct") BUILTIN(__builtin_elementwise_max, "v.", "nct") diff --git a/clang/lib/CodeGen/CGBuiltin.cpp b/clang/lib/CodeGen/CGBuiltin.cpp --- a/clang/lib/CodeGen/CGBuiltin.cpp +++ b/clang/lib/CodeGen/CGBuiltin.cpp @@ -2472,7 +2472,7 @@ return RValue::get(emitUnaryMaybeConstrainedFPBuiltin(*this, E, Intrinsic::roundeven, Intrinsic::experimental_constrained_roundeven)); - + case Builtin::BIsin: case Builtin::BIsinf: case Builtin::BIsinl: @@ -3904,6 +3904,14 @@ return RValue::get(Ptr); } + case Builtin::BI__builtin_implicit_object_fence: { + const Expr *Arg = E->getArg(0); + Value *Ptr = EmitScalarExpr(Arg); + Function *F = + Intrinsic::getDeclaration(&CGM.getModule(), Intrinsic::tbaa_fence); + Value *Result = Builder.CreateCall(F, {Ptr}); + return RValue::get(Result); + } case Builtin::BI__sync_fetch_and_add: case Builtin::BI__sync_fetch_and_sub: case Builtin::BI__sync_fetch_and_or: diff --git a/clang/test/CodeGen/builtin-implicit-object-fence.c b/clang/test/CodeGen/builtin-implicit-object-fence.c new file mode 100644 --- /dev/null +++ b/clang/test/CodeGen/builtin-implicit-object-fence.c @@ -0,0 +1,19 @@ +// NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py +// RUN: %clang_cc1 -triple x86_64-unknown-unknown -emit-llvm -o - %s | FileCheck %s + +// CHECK-LABEL: @test1( +// CHECK-NEXT: entry: +// CHECK-NEXT: [[A_ADDR:%.*]] = alloca ptr, align 8 +// CHECK-NEXT: [[B:%.*]] = alloca ptr, align 8 +// CHECK-NEXT: store ptr [[A:%.*]], ptr [[A_ADDR]], align 8 +// CHECK-NEXT: [[TMP0:%.*]] = load ptr, ptr [[A_ADDR]], align 8 +// CHECK-NEXT: [[TMP1:%.*]] = call ptr @llvm.tbaa.fence(ptr [[TMP0]]) +// CHECK-NEXT: store ptr [[TMP1]], ptr [[B]], align 8 +// CHECK-NEXT: [[TMP2:%.*]] = load ptr, ptr [[B]], align 8 +// CHECK-NEXT: [[TMP3:%.*]] = load float, ptr [[TMP2]], align 4 +// CHECK-NEXT: ret float [[TMP3]] +// +float test1(int *a) { + float *b = __builtin_implicit_object_fence(a); + return *b; +}