summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorReid Kleckner <rnk@google.com>2019-03-28 22:59:09 +0000
committerReid Kleckner <rnk@google.com>2019-03-28 22:59:09 +0000
commitc78aff6fa276b5164a89c3d078631dd2e0a2cab1 (patch)
treebd7d5718a16c351c8c1e78aaaa68c2f4b37ad699
parent522c8dac2d3d16fe43cae5a9a709e58ffd469a70 (diff)
[MS] Make __iso_volatile_* available on all targets
Future versions of MSVC make these intrinsics available on x86 & x64, according to: http://lists.llvm.org/pipermail/cfe-dev/2019-March/061711.html The purpose of these builtins is to emit plain, non-atomic, volatile stores when /volatile:ms (-cc1 -fms-volatile) is enabled. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@357220 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r--include/clang/Basic/Builtins.def8
-rw-r--r--include/clang/Basic/BuiltinsAArch64.def10
-rw-r--r--include/clang/Basic/BuiltinsARM.def8
-rw-r--r--lib/CodeGen/CGBuiltin.cpp92
-rw-r--r--lib/CodeGen/CodeGenFunction.h3
-rw-r--r--test/CodeGen/ms-intrinsics.c29
-rw-r--r--test/CodeGen/ms-volatile-aarch64.c13
-rw-r--r--test/CodeGen/ms-volatile-arm.c13
8 files changed, 78 insertions, 98 deletions
diff --git a/include/clang/Basic/Builtins.def b/include/clang/Basic/Builtins.def
index 18399926ec..7c860f94d7 100644
--- a/include/clang/Basic/Builtins.def
+++ b/include/clang/Basic/Builtins.def
@@ -820,6 +820,14 @@ LANGBUILTIN(_interlockedbittestandset64, "UcWiD*Wi", "n", ALL_MS_LANGUAGES)
LANGBUILTIN(_interlockedbittestandset_acq, "UcNiD*Ni", "n", ALL_MS_LANGUAGES)
LANGBUILTIN(_interlockedbittestandset_nf, "UcNiD*Ni", "n", ALL_MS_LANGUAGES)
LANGBUILTIN(_interlockedbittestandset_rel, "UcNiD*Ni", "n", ALL_MS_LANGUAGES)
+LANGBUILTIN(__iso_volatile_load8, "ccCD*", "n", ALL_MS_LANGUAGES)
+LANGBUILTIN(__iso_volatile_load16, "ssCD*", "n", ALL_MS_LANGUAGES)
+LANGBUILTIN(__iso_volatile_load32, "iiCD*", "n", ALL_MS_LANGUAGES)
+LANGBUILTIN(__iso_volatile_load64, "LLiLLiCD*", "n", ALL_MS_LANGUAGES)
+LANGBUILTIN(__iso_volatile_store8, "vcD*c", "n", ALL_MS_LANGUAGES)
+LANGBUILTIN(__iso_volatile_store16, "vsD*s", "n", ALL_MS_LANGUAGES)
+LANGBUILTIN(__iso_volatile_store32, "viD*i", "n", ALL_MS_LANGUAGES)
+LANGBUILTIN(__iso_volatile_store64, "vLLiD*LLi", "n", ALL_MS_LANGUAGES)
LANGBUILTIN(__noop, "i.", "n", ALL_MS_LANGUAGES)
LANGBUILTIN(__lzcnt16, "UsUs", "nc", ALL_MS_LANGUAGES)
LANGBUILTIN(__lzcnt, "UiUi", "nc", ALL_MS_LANGUAGES)
diff --git a/include/clang/Basic/BuiltinsAArch64.def b/include/clang/Basic/BuiltinsAArch64.def
index e9a8a2c44c..9486a905f6 100644
--- a/include/clang/Basic/BuiltinsAArch64.def
+++ b/include/clang/Basic/BuiltinsAArch64.def
@@ -78,16 +78,6 @@ LANGBUILTIN(__wfi, "v", "", ALL_MS_LANGUAGES)
LANGBUILTIN(__sev, "v", "", ALL_MS_LANGUAGES)
LANGBUILTIN(__sevl, "v", "", ALL_MS_LANGUAGES)
-// MSVC intrinsics for volatile but non-acquire/release loads and stores
-LANGBUILTIN(__iso_volatile_load8, "ccCD*", "n", ALL_MS_LANGUAGES)
-LANGBUILTIN(__iso_volatile_load16, "ssCD*", "n", ALL_MS_LANGUAGES)
-LANGBUILTIN(__iso_volatile_load32, "iiCD*", "n", ALL_MS_LANGUAGES)
-LANGBUILTIN(__iso_volatile_load64, "LLiLLiCD*", "n", ALL_MS_LANGUAGES)
-LANGBUILTIN(__iso_volatile_store8, "vcD*c", "n", ALL_MS_LANGUAGES)
-LANGBUILTIN(__iso_volatile_store16, "vsD*s", "n", ALL_MS_LANGUAGES)
-LANGBUILTIN(__iso_volatile_store32, "viD*i", "n", ALL_MS_LANGUAGES)
-LANGBUILTIN(__iso_volatile_store64, "vLLiD*LLi", "n", ALL_MS_LANGUAGES)
-
TARGET_HEADER_BUILTIN(_BitScanForward, "UcUNi*UNi", "nh", "intrin.h", ALL_MS_LANGUAGES, "")
TARGET_HEADER_BUILTIN(_BitScanReverse, "UcUNi*UNi", "nh", "intrin.h", ALL_MS_LANGUAGES, "")
TARGET_HEADER_BUILTIN(_BitScanForward64, "UcUNi*ULLi", "nh", "intrin.h", ALL_MS_LANGUAGES, "")
diff --git a/include/clang/Basic/BuiltinsARM.def b/include/clang/Basic/BuiltinsARM.def
index 000604558a..3f0765115b 100644
--- a/include/clang/Basic/BuiltinsARM.def
+++ b/include/clang/Basic/BuiltinsARM.def
@@ -201,14 +201,6 @@ LANGBUILTIN(__sevl, "v", "", ALL_MS_LANGUAGES)
LANGBUILTIN(__dmb, "vUi", "nc", ALL_MS_LANGUAGES)
LANGBUILTIN(__dsb, "vUi", "nc", ALL_MS_LANGUAGES)
LANGBUILTIN(__isb, "vUi", "nc", ALL_MS_LANGUAGES)
-LANGBUILTIN(__iso_volatile_load8, "ccCD*", "n", ALL_MS_LANGUAGES)
-LANGBUILTIN(__iso_volatile_load16, "ssCD*", "n", ALL_MS_LANGUAGES)
-LANGBUILTIN(__iso_volatile_load32, "iiCD*", "n", ALL_MS_LANGUAGES)
-LANGBUILTIN(__iso_volatile_load64, "LLiLLiCD*", "n", ALL_MS_LANGUAGES)
-LANGBUILTIN(__iso_volatile_store8, "vcD*c", "n", ALL_MS_LANGUAGES)
-LANGBUILTIN(__iso_volatile_store16, "vsD*s", "n", ALL_MS_LANGUAGES)
-LANGBUILTIN(__iso_volatile_store32, "viD*i", "n", ALL_MS_LANGUAGES)
-LANGBUILTIN(__iso_volatile_store64, "vLLiD*LLi", "n", ALL_MS_LANGUAGES)
LANGBUILTIN(__ldrexd, "WiWiCD*", "", ALL_MS_LANGUAGES)
LANGBUILTIN(_MoveFromCoprocessor, "UiIUiIUiIUiIUiIUi", "", ALL_MS_LANGUAGES)
LANGBUILTIN(_MoveFromCoprocessor2, "UiIUiIUiIUiIUiIUi", "", ALL_MS_LANGUAGES)
diff --git a/lib/CodeGen/CGBuiltin.cpp b/lib/CodeGen/CGBuiltin.cpp
index 5042d09227..72a336b104 100644
--- a/lib/CodeGen/CGBuiltin.cpp
+++ b/lib/CodeGen/CGBuiltin.cpp
@@ -298,6 +298,34 @@ static Value *EmitAtomicDecrementValue(CodeGenFunction &CGF, const CallExpr *E,
return CGF.Builder.CreateSub(Result, ConstantInt::get(IntTy, 1));
}
+// Build a plain volatile load.
+static Value *EmitISOVolatileLoad(CodeGenFunction &CGF, const CallExpr *E) {
+ Value *Ptr = CGF.EmitScalarExpr(E->getArg(0));
+ QualType ElTy = E->getArg(0)->getType()->getPointeeType();
+ CharUnits LoadSize = CGF.getContext().getTypeSizeInChars(ElTy);
+ llvm::Type *ITy =
+ llvm::IntegerType::get(CGF.getLLVMContext(), LoadSize.getQuantity() * 8);
+ Ptr = CGF.Builder.CreateBitCast(Ptr, ITy->getPointerTo());
+ llvm::LoadInst *Load = CGF.Builder.CreateAlignedLoad(Ptr, LoadSize);
+ Load->setVolatile(true);
+ return Load;
+}
+
+// Build a plain volatile store.
+static Value *EmitISOVolatileStore(CodeGenFunction &CGF, const CallExpr *E) {
+ Value *Ptr = CGF.EmitScalarExpr(E->getArg(0));
+ Value *Value = CGF.EmitScalarExpr(E->getArg(1));
+ QualType ElTy = E->getArg(0)->getType()->getPointeeType();
+ CharUnits StoreSize = CGF.getContext().getTypeSizeInChars(ElTy);
+ llvm::Type *ITy =
+ llvm::IntegerType::get(CGF.getLLVMContext(), StoreSize.getQuantity() * 8);
+ Ptr = CGF.Builder.CreateBitCast(Ptr, ITy->getPointerTo());
+ llvm::StoreInst *Store =
+ CGF.Builder.CreateAlignedStore(Value, Ptr, StoreSize);
+ Store->setVolatile(true);
+ return Store;
+}
+
// Emit a simple mangled intrinsic that has 1 argument and a return type
// matching the argument type.
static Value *emitUnaryBuiltin(CodeGenFunction &CGF,
@@ -3341,6 +3369,19 @@ RValue CodeGenFunction::EmitBuiltinExpr(const GlobalDecl GD, unsigned BuiltinID,
case Builtin::BI_interlockedbittestandreset_nf:
return RValue::get(EmitBitTestIntrinsic(*this, BuiltinID, E));
+ // These builtins exist to emit regular volatile loads and stores not
+ // affected by the -fms-volatile setting.
+ case Builtin::BI__iso_volatile_load8:
+ case Builtin::BI__iso_volatile_load16:
+ case Builtin::BI__iso_volatile_load32:
+ case Builtin::BI__iso_volatile_load64:
+ return RValue::get(EmitISOVolatileLoad(*this, E));
+ case Builtin::BI__iso_volatile_store8:
+ case Builtin::BI__iso_volatile_store16:
+ case Builtin::BI__iso_volatile_store32:
+ case Builtin::BI__iso_volatile_store64:
+ return RValue::get(EmitISOVolatileStore(*this, E));
+
case Builtin::BI__exception_code:
case Builtin::BI_exception_code:
return RValue::get(EmitSEHExceptionCode());
@@ -5835,34 +5876,6 @@ static bool HasExtraNeonArgument(unsigned BuiltinID) {
return true;
}
-Value *CodeGenFunction::EmitISOVolatileLoad(const CallExpr *E) {
- Value *Ptr = EmitScalarExpr(E->getArg(0));
- QualType ElTy = E->getArg(0)->getType()->getPointeeType();
- CharUnits LoadSize = getContext().getTypeSizeInChars(ElTy);
- llvm::Type *ITy = llvm::IntegerType::get(getLLVMContext(),
- LoadSize.getQuantity() * 8);
- Ptr = Builder.CreateBitCast(Ptr, ITy->getPointerTo());
- llvm::LoadInst *Load =
- Builder.CreateAlignedLoad(Ptr, LoadSize);
- Load->setVolatile(true);
- return Load;
-}
-
-Value *CodeGenFunction::EmitISOVolatileStore(const CallExpr *E) {
- Value *Ptr = EmitScalarExpr(E->getArg(0));
- Value *Value = EmitScalarExpr(E->getArg(1));
- QualType ElTy = E->getArg(0)->getType()->getPointeeType();
- CharUnits StoreSize = getContext().getTypeSizeInChars(ElTy);
- llvm::Type *ITy = llvm::IntegerType::get(getLLVMContext(),
- StoreSize.getQuantity() * 8);
- Ptr = Builder.CreateBitCast(Ptr, ITy->getPointerTo());
- llvm::StoreInst *Store =
- Builder.CreateAlignedStore(Value, Ptr,
- StoreSize);
- Store->setVolatile(true);
- return Store;
-}
-
Value *CodeGenFunction::EmitARMBuiltinExpr(unsigned BuiltinID,
const CallExpr *E,
llvm::Triple::ArchType Arch) {
@@ -6102,19 +6115,6 @@ Value *CodeGenFunction::EmitARMBuiltinExpr(unsigned BuiltinID,
return Builder.CreateCall(F, {StoreVal, StoreAddr}, "strex");
}
- switch (BuiltinID) {
- case ARM::BI__iso_volatile_load8:
- case ARM::BI__iso_volatile_load16:
- case ARM::BI__iso_volatile_load32:
- case ARM::BI__iso_volatile_load64:
- return EmitISOVolatileLoad(E);
- case ARM::BI__iso_volatile_store8:
- case ARM::BI__iso_volatile_store16:
- case ARM::BI__iso_volatile_store32:
- case ARM::BI__iso_volatile_store64:
- return EmitISOVolatileStore(E);
- }
-
if (BuiltinID == ARM::BI__builtin_arm_clrex) {
Function *F = CGM.getIntrinsic(Intrinsic::arm_clrex);
return Builder.CreateCall(F);
@@ -8926,16 +8926,6 @@ Value *CodeGenFunction::EmitAArch64BuiltinExpr(unsigned BuiltinID,
Int = Intrinsic::aarch64_neon_suqadd;
return EmitNeonCall(CGM.getIntrinsic(Int, Ty), Ops, "vuqadd");
}
- case AArch64::BI__iso_volatile_load8:
- case AArch64::BI__iso_volatile_load16:
- case AArch64::BI__iso_volatile_load32:
- case AArch64::BI__iso_volatile_load64:
- return EmitISOVolatileLoad(E);
- case AArch64::BI__iso_volatile_store8:
- case AArch64::BI__iso_volatile_store16:
- case AArch64::BI__iso_volatile_store32:
- case AArch64::BI__iso_volatile_store64:
- return EmitISOVolatileStore(E);
case AArch64::BI_BitScanForward:
case AArch64::BI_BitScanForward64:
return EmitMSVCBuiltinExpr(MSVCIntrin::_BitScanForward, E);
diff --git a/lib/CodeGen/CodeGenFunction.h b/lib/CodeGen/CodeGenFunction.h
index 7d8cf45dd8..c24fc77d6d 100644
--- a/lib/CodeGen/CodeGenFunction.h
+++ b/lib/CodeGen/CodeGenFunction.h
@@ -3728,9 +3728,6 @@ public:
Address PtrOp0, Address PtrOp1,
llvm::Triple::ArchType Arch);
- llvm::Value *EmitISOVolatileLoad(const CallExpr *E);
- llvm::Value *EmitISOVolatileStore(const CallExpr *E);
-
llvm::Function *LookupNeonLLVMIntrinsic(unsigned IntrinsicID,
unsigned Modifier, llvm::Type *ArgTy,
const CallExpr *E);
diff --git a/test/CodeGen/ms-intrinsics.c b/test/CodeGen/ms-intrinsics.c
index 59ddaf8c10..cf41d23d35 100644
--- a/test/CodeGen/ms-intrinsics.c
+++ b/test/CodeGen/ms-intrinsics.c
@@ -494,6 +494,35 @@ long test_InterlockedDecrement(long volatile *Addend) {
// CHECK: ret i32 [[RESULT]]
// CHECK: }
+char test_iso_volatile_load8(char volatile *p) { return __iso_volatile_load8(p); }
+short test_iso_volatile_load16(short volatile *p) { return __iso_volatile_load16(p); }
+int test_iso_volatile_load32(int volatile *p) { return __iso_volatile_load32(p); }
+__int64 test_iso_volatile_load64(__int64 volatile *p) { return __iso_volatile_load64(p); }
+
+// CHECK: define{{.*}}i8 @test_iso_volatile_load8(i8*{{[a-z_ ]*}}%p)
+// CHECK: = load volatile i8, i8* %p
+// CHECK: define{{.*}}i16 @test_iso_volatile_load16(i16*{{[a-z_ ]*}}%p)
+// CHECK: = load volatile i16, i16* %p
+// CHECK: define{{.*}}i32 @test_iso_volatile_load32(i32*{{[a-z_ ]*}}%p)
+// CHECK: = load volatile i32, i32* %p
+// CHECK: define{{.*}}i64 @test_iso_volatile_load64(i64*{{[a-z_ ]*}}%p)
+// CHECK: = load volatile i64, i64* %p
+
+void test_iso_volatile_store8(char volatile *p, char v) { __iso_volatile_store8(p, v); }
+void test_iso_volatile_store16(short volatile *p, short v) { __iso_volatile_store16(p, v); }
+void test_iso_volatile_store32(int volatile *p, int v) { __iso_volatile_store32(p, v); }
+void test_iso_volatile_store64(__int64 volatile *p, __int64 v) { __iso_volatile_store64(p, v); }
+
+// CHECK: define{{.*}}void @test_iso_volatile_store8(i8*{{[a-z_ ]*}}%p, i8 {{[a-z_ ]*}}%v)
+// CHECK: store volatile i8 %v, i8* %p
+// CHECK: define{{.*}}void @test_iso_volatile_store16(i16*{{[a-z_ ]*}}%p, i16 {{[a-z_ ]*}}%v)
+// CHECK: store volatile i16 %v, i16* %p
+// CHECK: define{{.*}}void @test_iso_volatile_store32(i32*{{[a-z_ ]*}}%p, i32 {{[a-z_ ]*}}%v)
+// CHECK: store volatile i32 %v, i32* %p
+// CHECK: define{{.*}}void @test_iso_volatile_store64(i64*{{[a-z_ ]*}}%p, i64 {{[a-z_ ]*}}%v)
+// CHECK: store volatile i64 %v, i64* %p
+
+
#if defined(__x86_64__) || defined(__arm__) || defined(__aarch64__)
__int64 test_InterlockedExchange64(__int64 volatile *value, __int64 mask) {
return _InterlockedExchange64(value, mask);
diff --git a/test/CodeGen/ms-volatile-aarch64.c b/test/CodeGen/ms-volatile-aarch64.c
deleted file mode 100644
index 2a139f5139..0000000000
--- a/test/CodeGen/ms-volatile-aarch64.c
+++ /dev/null
@@ -1,13 +0,0 @@
-// REQUIRES: aarch64-registered-target
-// RUN: %clang_cc1 -triple aarch64-win32 -emit-llvm -fms-extensions -fms-volatile -o - < %s | FileCheck %s
-
-void test1(int volatile *p, int v) {
- __iso_volatile_store32(p, v);
- // CHECK-LABEL: @test1
- // CHECK: store volatile {{.*}}, {{.*}}
-}
-int test2(const int volatile *p) {
- return __iso_volatile_load32(p);
- // CHECK-LABEL: @test2
- // CHECK: load volatile {{.*}}
-}
diff --git a/test/CodeGen/ms-volatile-arm.c b/test/CodeGen/ms-volatile-arm.c
deleted file mode 100644
index 065e624a4c..0000000000
--- a/test/CodeGen/ms-volatile-arm.c
+++ /dev/null
@@ -1,13 +0,0 @@
-// REQUIRES: arm-registered-target
-// RUN: %clang_cc1 -triple thumbv7-win32 -emit-llvm -fms-extensions -fms-volatile -o - < %s | FileCheck %s
-
-void test1(int volatile *p, int v) {
- __iso_volatile_store32(p, v);
- // CHECK-LABEL: @test1
- // CHECK: store volatile {{.*}}, {{.*}}
-}
-int test2(const int volatile *p) {
- return __iso_volatile_load32(p);
- // CHECK-LABEL: @test2
- // CHECK: load volatile {{.*}}
-}