[PATCH] D62394: [ARM][CMSE] Add CMSE header & builtins

2019-09-17 Thread Javed Absar via Phabricator via cfe-commits
javed.absar added a comment.

In D62394#1672551 , @sigvartmh wrote:

> Maybe I'm doing something wrong tried to apply these patches but when trying 
> to build code which uses cmse I get
>
> Cannot select: intrinsic %llvm.arm.cmse.tt
>  fatal error: error in backend: Cannot select: intrinsic %llvm.arm.cmse.tt
>  clang-10: error: clang frontend command failed with exit code 70 (use -v to 
> see invocation)
>
> Built llvm with clang,compiler-rt,lld from master.


Did you try to build and run lit tests successfully with this patch before 
trying your own tests?


CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D62394/new/

https://reviews.llvm.org/D62394



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D62394: [ARM][CMSE] Add CMSE header & builtins

2019-05-24 Thread Javed Absar via Phabricator via cfe-commits
javed.absar created this revision.
javed.absar added reviewers: snidertm, dmgreen.
Herald added subscribers: kristof.beyls, mgorny.

This is patch C2 as mentioned in RFC 
http://lists.llvm.org/pipermail/cfe-dev/2019-March/061834.html

This adds cmse builtin functions, and introduces arm_cmse.h header which has  
useful macros, functions and data types for end-users of cmse.


https://reviews.llvm.org/D62394

Files:
  include/clang/Basic/BuiltinsARM.def
  lib/Headers/CMakeLists.txt
  lib/Headers/arm_cmse.h
  test/CodeGen/arm-cmse-nonsecure.c
  test/CodeGen/arm-cmse-secure.c
  test/CodeGen/arm-cmse.c
  test/Headers/arm-cmse-header-ns.c
  test/Headers/arm-cmse-header.c

Index: test/Headers/arm-cmse-header.c
===
--- /dev/null
+++ test/Headers/arm-cmse-header.c
@@ -0,0 +1,20 @@
+// RUN: %clang_cc1 -triple thumbv8m.base-linux-gnueabihf  -fsyntax-only -ffreestanding %s -verify -mcmse
+// RUN: %clang_cc1 -triple thumbv8m.base-linux-gnueabihf  -fsyntax-only -ffreestanding -x c++ %s -verify -mcmse
+// expected-no-diagnostics
+
+#include 
+
+typedef void (*callback_t)(void);
+
+void func(callback_t fptr, void *p)
+{
+  cmse_TT(p);
+  cmse_TTT(p);
+  cmse_TTA(p);
+  cmse_TTAT(p);
+
+  cmse_TT_fptr(fptr);
+  cmse_TTT_fptr(fptr);
+  cmse_TTA_fptr(fptr);
+  cmse_TTAT_fptr(fptr);
+}
Index: test/Headers/arm-cmse-header-ns.c
===
--- /dev/null
+++ test/Headers/arm-cmse-header-ns.c
@@ -0,0 +1,27 @@
+// RUN: %clang_cc1 -triple thumbv8m.base-linux-gnueabihf  -fsyntax-only -ffreestanding %s 2>&1 | FileCheck --check-prefix=CHECK-c %s
+// RUN: not %clang_cc1 -triple thumbv8m.base-linux-gnueabihf  -fsyntax-only -ffreestanding -x c++ %s 2>&1 | FileCheck --check-prefix=CHECK-cpp %s
+
+#include 
+
+typedef void (*callback_t)(void);
+
+void func(callback_t fptr, void *p)
+{
+  cmse_TT(p);
+  cmse_TTT(p);
+  cmse_TT_fptr(fptr);
+  cmse_TTT_fptr(fptr);
+
+  cmse_TTA(p);
+  cmse_TTAT(p);
+  cmse_TTA_fptr(fptr);
+  cmse_TTAT_fptr(fptr);
+// CHECK-c: warning: implicit declaration of function 'cmse_TTA'
+// CHECK-c: warning: implicit declaration of function 'cmse_TTAT'
+// CHECK-c: warning: implicit declaration of function 'cmse_TTA_fptr'
+// CHECK-c: warning: implicit declaration of function 'cmse_TTAT_fptr'
+// CHECK-cpp: error: use of undeclared identifier 'cmse_TTA'
+// CHECK-cpp: error: use of undeclared identifier 'cmse_TTAT'
+// CHECK-cpp: error: use of undeclared identifier 'cmse_TTA_fptr'
+// CHECK-cpp: error: use of undeclared identifier 'cmse_TTAT_fptr'
+}
Index: test/CodeGen/arm-cmse.c
===
--- /dev/null
+++ test/CodeGen/arm-cmse.c
@@ -0,0 +1,20 @@
+// RUN: %clang_cc1 -triple thumbv8m.base-none-eabi -O1 -emit-llvm %s -o - | FileCheck %s
+int test_cmse_TT(void *p){
+  return __builtin_arm_cmse_TT(p);
+  // CHECK: call i32 @llvm.arm.cmse.tt(i8* %{{.*}})
+}
+
+int test_cmse_TTT(void *p){
+  return __builtin_arm_cmse_TTT(p);
+  // CHECK: call i32 @llvm.arm.cmse.ttt(i8* %{{.*}})
+}
+
+int test_cmse_TTA(void *p){
+  return __builtin_arm_cmse_TTA(p);
+  // CHECK: call i32 @llvm.arm.cmse.tta(i8* %{{.*}})
+}
+
+int test_cmse_TTAT(void *p){
+  return __builtin_arm_cmse_TTAT(p);
+  // CHECK: call i32 @llvm.arm.cmse.ttat(i8* %{{.*}})
+}
Index: test/CodeGen/arm-cmse-secure.c
===
--- /dev/null
+++ test/CodeGen/arm-cmse-secure.c
@@ -0,0 +1,66 @@
+// RUN: %clang -fvisibility=default -mlittle-endian -mcmse -Xclang -ffreestanding -target thumbv8m.base-linux-gnueabihf -emit-llvm -S -o - %s | FileCheck %s
+// RUN: %clang -fvisibility=default -mbig-endian-mcmse -Xclang -ffreestanding -target thumbv8m.base-linux-gnueabihf -emit-llvm -S -o - %s | FileCheck %s
+
+#include 
+
+unsigned test_cmse_primitives(void *p) {
+// CHECK: define {{.*}} i32 @test_cmse_primitives
+  cmse_address_info_t tt_val, ttt_val;
+  cmse_address_info_t tta_val, ttat_val;
+  unsigned sum;
+
+  tt_val = cmse_TT(p);
+  ttt_val = cmse_TTT(p);
+  tta_val = cmse_TTA(p);
+  ttat_val = cmse_TTAT(p);
+// CHECK: call i32 @llvm.arm.cmse.tt
+// CHECK: call i32 @llvm.arm.cmse.ttt
+// CHECK: call i32 @llvm.arm.cmse.tta
+// CHECK: call i32 @llvm.arm.cmse.ttat
+
+  sum = tt_val.value;
+  sum += ttt_val.value;
+  sum += tta_val.value;
+  sum += ttat_val.value;
+
+  sum += tt_val.flags.mpu_region;
+  sum += tt_val.flags.sau_region;
+  sum += tt_val.flags.mpu_region_valid;
+  sum += tt_val.flags.sau_region_valid;
+  sum += tt_val.flags.read_ok;
+  sum += tt_val.flags.readwrite_ok;
+  sum += tt_val.flags.nonsecure_read_ok;
+  sum += tt_val.flags.nonsecure_readwrite_ok;
+  sum += tt_val.flags.secure;
+  sum += tt_val.flags.idau_region_valid;
+  sum += tt_val.flags.idau_region;
+
+  return sum;
+}
+
+void *test_address_range(void *p) {
+// CHECK: define {{.*}} i8* @test_address_range
+  return cmse_check_address_range(p, 128, CMSE_MPU_UNPRIV
+  

[PATCH] D59879: [ARM][CMSE] Add commandline option and feature macro

2019-05-21 Thread Javed Absar via Phabricator via cfe-commits
This revision was automatically updated to reflect the committed changes.
Closed by commit rC361261: [ARM][CMSE] Add commandline option and feature macro 
(authored by javed.absar, committed by ).

Repository:
  rC Clang

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D59879/new/

https://reviews.llvm.org/D59879

Files:
  include/clang/Basic/Attr.td
  include/clang/Basic/DiagnosticCommonKinds.td
  include/clang/Basic/LangOptions.def
  include/clang/Driver/Options.td
  lib/Basic/Targets/ARM.cpp
  lib/Driver/ToolChains/Arch/ARM.cpp
  lib/Driver/ToolChains/Clang.cpp
  lib/Frontend/CompilerInvocation.cpp
  test/Preprocessor/arm-target-features.c

Index: include/clang/Driver/Options.td
===
--- include/clang/Driver/Options.td
+++ include/clang/Driver/Options.td
@@ -2143,6 +2143,9 @@
   HelpText<"Disallow use of CRC instructions (ARM only)">;
 def mno_neg_immediates: Flag<["-"], "mno-neg-immediates">, Group,
   HelpText<"Disallow converting instructions with negative immediates to their negation or inversion.">;
+def mcmse : Flag<["-"], "mcmse">, Group,
+  Flags<[DriverOption,CC1Option]>,
+  HelpText<"Allow use of CMSE (Armv8-M Security Extensions)">;
 
 def mgeneral_regs_only : Flag<["-"], "mgeneral-regs-only">, Group,
   HelpText<"Generate code which only uses the general purpose registers (AArch64 only)">;
Index: include/clang/Basic/Attr.td
===
--- include/clang/Basic/Attr.td
+++ include/clang/Basic/Attr.td
@@ -299,6 +299,9 @@
 def BlocksSupported : LangOpt<"Blocks">;
 def ObjCAutoRefCount : LangOpt<"ObjCAutoRefCount">;
 
+// Language option for CMSE extensions
+def Cmse : LangOpt<"Cmse">;
+
 // Defines targets for target-specific attributes. Empty lists are unchecked.
 class TargetSpec {
   // Specifies Architectures for which the target applies, based off the
Index: include/clang/Basic/LangOptions.def
===
--- include/clang/Basic/LangOptions.def
+++ include/clang/Basic/LangOptions.def
@@ -300,6 +300,8 @@
"field padding (0: none, 1:least "
"aggressive, 2: more aggressive)")
 
+LANGOPT(Cmse, 1, 0, "ARM Security extensions support")
+
 LANGOPT(XRayInstrument, 1, 0, "controls whether to do XRay instrumentation")
 LANGOPT(XRayAlwaysEmitCustomEvents, 1, 0,
 "controls whether to always emit intrinsic calls to "
Index: include/clang/Basic/DiagnosticCommonKinds.td
===
--- include/clang/Basic/DiagnosticCommonKinds.td
+++ include/clang/Basic/DiagnosticCommonKinds.td
@@ -252,6 +252,8 @@
   "the %0 sub-architecture does not support unaligned accesses">;
 def err_target_unsupported_execute_only : Error<
   "execute only is not supported for the %0 sub-architecture">;
+def err_target_unsupported_mcmse : Error<
+  "-mcmse is not supported for %0">;
 def err_opt_not_valid_with_opt : Error<
   "option '%0' cannot be specified with '%1'">;
 def err_opt_not_valid_without_opt : Error<
Index: test/Preprocessor/arm-target-features.c
===
--- test/Preprocessor/arm-target-features.c
+++ test/Preprocessor/arm-target-features.c
@@ -198,6 +198,7 @@
 // V8M_BASELINE: #define __ARM_ARCH_ISA_THUMB 1
 // V8M_BASELINE: #define __ARM_ARCH_PROFILE 'M'
 // V8M_BASELINE-NOT: __ARM_FEATURE_CRC32
+// V8M_BASELINE: #define __ARM_FEATURE_CMSE 1
 // V8M_BASELINE-NOT: __ARM_FEATURE_DSP
 // V8M_BASELINE-NOT: __ARM_FP 0x{{.*}}
 // V8M_BASELINE-NOT: __GCC_HAVE_SYNC_COMPARE_AND_SWAP_1
@@ -210,6 +211,7 @@
 // V8M_MAINLINE: #define __ARM_ARCH_ISA_THUMB 2
 // V8M_MAINLINE: #define __ARM_ARCH_PROFILE 'M'
 // V8M_MAINLINE-NOT: __ARM_FEATURE_CRC32
+// V8M_MAINLINE: #define __ARM_FEATURE_CMSE 1
 // V8M_MAINLINE-NOT: __ARM_FEATURE_DSP
 // V8M_MAINLINE-NOT: #define __ARM_FP 0x
 // V8M_MAINLINE: #define __GCC_HAVE_SYNC_COMPARE_AND_SWAP_1 1
@@ -675,6 +677,24 @@
 // M7-THUMB-ALLOW-FP-INSTR:#define __ARM_FP 0xe
 // M7-THUMB-ALLOW-FP-INSTR:#define __ARM_FPV5__ 1
 
+// Check that -mcmse (security extension) option works correctly for v8-M targets
+// RUN: %clang -target armv8m.base-none-linux-gnu -mcmse -x c -E -dM %s -o - | FileCheck -match-full-lines --check-prefix=V8M_CMSE %s
+// RUN: %clang -target armv8m.main-none-linux-gnu -mcmse -x c -E -dM %s -o - | FileCheck -match-full-lines --check-prefix=V8M_CMSE %s
+// RUN: %clang -target arm-none-linux-gnu -mcpu=cortex-m33 -mcmse -x c -E -dM %s -o - | FileCheck -match-full-lines --check-prefix=V8M_CMSE %s
+// RUN: %clang -target arm -mcpu=cortex-m23 -mcmse -x c -E -dM %s -o - | FileCheck -match-full-lines --check-prefix=V8M_CMSE %s
+// V8M_CMSE-NOT: __ARM_FEATURE_CMSE 1
+// V8M_CMSE: #define __ARM_FEATURE_CMSE 3
+
+// Check that CMSE is not defined on architectures w/o support for security extension
+// RUN: 

[PATCH] D59879: [ARM][CMSE] Add commandline option and feature macro

2019-05-16 Thread Javed Absar via Phabricator via cfe-commits
javed.absar updated this revision to Diff 199819.
javed.absar added a comment.

Updated based on review comments


CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D59879/new/

https://reviews.llvm.org/D59879

Files:
  include/clang/Basic/Attr.td
  include/clang/Basic/DiagnosticCommonKinds.td
  include/clang/Basic/LangOptions.def
  include/clang/Driver/Options.td
  lib/Basic/Targets/ARM.cpp
  lib/Driver/ToolChains/Arch/ARM.cpp
  lib/Driver/ToolChains/Clang.cpp
  lib/Frontend/CompilerInvocation.cpp
  test/Preprocessor/arm-target-features.c

Index: test/Preprocessor/arm-target-features.c
===
--- test/Preprocessor/arm-target-features.c
+++ test/Preprocessor/arm-target-features.c
@@ -198,6 +198,7 @@
 // V8M_BASELINE: #define __ARM_ARCH_ISA_THUMB 1
 // V8M_BASELINE: #define __ARM_ARCH_PROFILE 'M'
 // V8M_BASELINE-NOT: __ARM_FEATURE_CRC32
+// V8M_BASELINE: #define __ARM_FEATURE_CMSE 1
 // V8M_BASELINE-NOT: __ARM_FEATURE_DSP
 // V8M_BASELINE-NOT: __ARM_FP 0x{{.*}}
 // V8M_BASELINE-NOT: __GCC_HAVE_SYNC_COMPARE_AND_SWAP_1
@@ -210,6 +211,7 @@
 // V8M_MAINLINE: #define __ARM_ARCH_ISA_THUMB 2
 // V8M_MAINLINE: #define __ARM_ARCH_PROFILE 'M'
 // V8M_MAINLINE-NOT: __ARM_FEATURE_CRC32
+// V8M_MAINLINE: #define __ARM_FEATURE_CMSE 1
 // V8M_MAINLINE-NOT: __ARM_FEATURE_DSP
 // V8M_MAINLINE-NOT: #define __ARM_FP 0x
 // V8M_MAINLINE: #define __GCC_HAVE_SYNC_COMPARE_AND_SWAP_1 1
@@ -675,6 +677,24 @@
 // M7-THUMB-ALLOW-FP-INSTR:#define __ARM_FP 0xe
 // M7-THUMB-ALLOW-FP-INSTR:#define __ARM_FPV5__ 1
 
+// Check that -mcmse (security extension) option works correctly for v8-M targets
+// RUN: %clang -target armv8m.base-none-linux-gnu -mcmse -x c -E -dM %s -o - | FileCheck -match-full-lines --check-prefix=V8M_CMSE %s
+// RUN: %clang -target armv8m.main-none-linux-gnu -mcmse -x c -E -dM %s -o - | FileCheck -match-full-lines --check-prefix=V8M_CMSE %s
+// RUN: %clang -target arm-none-linux-gnu -mcpu=cortex-m33 -mcmse -x c -E -dM %s -o - | FileCheck -match-full-lines --check-prefix=V8M_CMSE %s
+// RUN: %clang -target arm -mcpu=cortex-m23 -mcmse -x c -E -dM %s -o - | FileCheck -match-full-lines --check-prefix=V8M_CMSE %s
+// V8M_CMSE-NOT: __ARM_FEATURE_CMSE 1
+// V8M_CMSE: #define __ARM_FEATURE_CMSE 3
+
+// Check that CMSE is not defined on architectures w/o support for security extension
+// RUN: %clang -target arm-arm-none-gnueabi -mcpu=cortex-a5 -x c -E -dM %s -o - | FileCheck -match-full-lines --check-prefix=NOTV8M_CMSE %s
+// RUN: %clang -target armv8a-none-linux-gnu -x c -E -dM %s -o - | FileCheck -match-full-lines --check-prefix=NOTV8M_CMSE %s
+// RUN: %clang -target armv8.1a-none-none-eabi -x c -E -dM %s -o - | FileCheck -match-full-lines --check-prefix=NOTV8M_CMSE %s
+// NOTV8M_CMSE-NOT: __ARM_FEATURE_CMSE
+
+// Check that -mcmse option gives error on non v8-M targets
+// RUN: not %clang -target arm-arm-none-eabi -mthumb -mcmse -mcpu=cortex-m7 -x c -E -dM %s -o - 2>&1 | FileCheck -match-full-lines --check-prefix=NOTV8MCMSE_OPT %s
+// NOTV8MCMSE_OPT: error: -mcmse is not supported for cortex-m7
+
 // Test whether predefines are as expected when targeting v8m cores
 // RUN: %clang -target arm -mcpu=cortex-m23 -x c -E -dM %s -o - | FileCheck -match-full-lines --check-prefix=M23 %s
 // M23: #define __ARM_ARCH 8
Index: lib/Frontend/CompilerInvocation.cpp
===
--- lib/Frontend/CompilerInvocation.cpp
+++ lib/Frontend/CompilerInvocation.cpp
@@ -2729,6 +2729,7 @@
   Opts.HalfArgsAndReturns = Args.hasArg(OPT_fallow_half_arguments_and_returns)
 | Opts.NativeHalfArgsAndReturns;
   Opts.GNUAsm = !Args.hasArg(OPT_fno_gnu_inline_asm);
+  Opts.Cmse = Args.hasArg(OPT_mcmse); // Armv8-M Security Extensions
 
   // __declspec is enabled by default for the PS4 by the driver, and also
   // enabled for Microsoft Extensions or Borland Extensions, here.
Index: lib/Driver/ToolChains/Clang.cpp
===
--- lib/Driver/ToolChains/Clang.cpp
+++ lib/Driver/ToolChains/Clang.cpp
@@ -1423,6 +1423,9 @@
   if (!Args.hasFlag(options::OPT_mimplicit_float,
 options::OPT_mno_implicit_float, true))
 CmdArgs.push_back("-no-implicit-float");
+
+  if (Args.getLastArg(options::OPT_mcmse))
+CmdArgs.push_back("-mcmse");
 }
 
 void Clang::RenderTargetOptions(const llvm::Triple ,
Index: lib/Driver/ToolChains/Arch/ARM.cpp
===
--- lib/Driver/ToolChains/Arch/ARM.cpp
+++ lib/Driver/ToolChains/Arch/ARM.cpp
@@ -469,6 +469,10 @@
 }
   }
 
+  // CMSE: Check for target 8M (for -mcmse to be applicable) is performed later.
+  if (Args.getLastArg(options::OPT_mcmse))
+Features.push_back("+8msecext");
+
   // Look for the last occurrence of -mlong-calls or -mno-long-calls. If
   // neither options are specified, see if we are compiling for kernel/kext and
   // decide 

[PATCH] D59879: [ARM][CMSE] Add commandline option and feature macro

2019-05-16 Thread Javed Absar via Phabricator via cfe-commits
javed.absar marked 4 inline comments as done.
javed.absar added inline comments.



Comment at: lib/Basic/Targets/ARM.cpp:438
+} else if (Feature == "+8msecext") {
+  if ((CPUProfile != "M" && CPUProfile != "B") || ArchVersion != 8) {
+Diags.Report(diag::err_target_unsupported_mcmse) << CPU;

snidertm wrote:
> dmgreen wrote:
> > snidertm wrote:
> > > How does CPUProfile get a value of "B"? I thought any Cortex-M processor 
> > > would set CPUProfile to "M". Is CMSE available on a processor besides 
> > > Cortex-m33?
> > "B" was going to be a very old name for v8m-baseline, looks like this one 
> > was never cleaned up when that was changed. You can drop the != "B" check.
> Do all v8 profile == 'M' processor variants support security extensions?
Yes


Repository:
  rC Clang

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D59879/new/

https://reviews.llvm.org/D59879



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D60485: [AArch64] Add support for MTE intrinsics

2019-04-26 Thread Javed Absar via Phabricator via cfe-commits
This revision was automatically updated to reflect the committed changes.
Closed by commit rC359348: [AArch64] Add support for MTE intrinsics (authored 
by javed.absar, committed by ).
Herald added a project: clang.

Changed prior to commit:
  https://reviews.llvm.org/D60485?vs=196297=196915#toc

Repository:
  rC Clang

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D60485/new/

https://reviews.llvm.org/D60485

Files:
  include/clang/Basic/BuiltinsAArch64.def
  include/clang/Basic/DiagnosticSemaKinds.td
  include/clang/Sema/Sema.h
  lib/Basic/Targets/AArch64.cpp
  lib/Basic/Targets/AArch64.h
  lib/CodeGen/CGBuiltin.cpp
  lib/Headers/arm_acle.h
  lib/Sema/SemaChecking.cpp
  test/CodeGen/arm64-mte.c
  test/Preprocessor/aarch64-target-features.c
  test/Sema/builtins-arm64-mte.c

Index: include/clang/Basic/DiagnosticSemaKinds.td
===
--- include/clang/Basic/DiagnosticSemaKinds.td
+++ include/clang/Basic/DiagnosticSemaKinds.td
@@ -9621,6 +9621,18 @@
"the type is not trivially copyable|"
"the type does not have the expected form}1">;
 
+// Memory Tagging Extensions (MTE) diagnostics
+def err_memtag_arg_null_or_pointer : Error<
+  "%0 argument of MTE builtin function must be a null or a pointer (%1 invalid)">;
+def err_memtag_any2arg_pointer : Error<
+  "at least one argument of MTE builtin function must be a pointer (%0, %1 invalid)">;
+def err_memtag_arg_must_be_pointer : Error<
+  "%0 argument of MTE builtin function must be a pointer (%1 invalid)">;
+def err_memtag_arg_must_be_integer : Error<
+  "%0 argument of MTE builtin function must be an integer type (%1 invalid)">;
+def err_memtag_arg_must_be_unsigned : Error<
+  "%0 argument  of MTE builtin function must be an unsigned integer type (%1 invalid)">;
+
 def warn_dereference_of_noderef_type : Warning<
   "dereferencing %0; was declared with a 'noderef' type">, InGroup;
 def warn_dereference_of_noderef_type_no_decl : Warning<
Index: include/clang/Basic/BuiltinsAArch64.def
===
--- include/clang/Basic/BuiltinsAArch64.def
+++ include/clang/Basic/BuiltinsAArch64.def
@@ -52,6 +52,14 @@
 BUILTIN(__builtin_arm_crc32d, "UiUiWUi", "nc")
 BUILTIN(__builtin_arm_crc32cd, "UiUiWUi", "nc")
 
+// Memory Tagging Extensions (MTE)
+BUILTIN(__builtin_arm_irg, "v*v*Ui", "t")
+BUILTIN(__builtin_arm_addg, "v*v*Ui", "t")
+BUILTIN(__builtin_arm_gmi, "Uiv*Ui", "t")
+BUILTIN(__builtin_arm_ldg, "v*v*", "t")
+BUILTIN(__builtin_arm_stg, "vv*", "t")
+BUILTIN(__builtin_arm_subp, "Uiv*v*", "t")
+
 // Memory barrier
 BUILTIN(__builtin_arm_dmb, "vUi", "nc")
 BUILTIN(__builtin_arm_dsb, "vUi", "nc")
Index: include/clang/Sema/Sema.h
===
--- include/clang/Sema/Sema.h
+++ include/clang/Sema/Sema.h
@@ -10759,6 +10759,7 @@
   bool SemaBuiltinARMSpecialReg(unsigned BuiltinID, CallExpr *TheCall,
 int ArgNum, unsigned ExpectedFieldNum,
 bool AllowName);
+  bool SemaBuiltinARMMemoryTaggingCall(unsigned BuiltinID, CallExpr *TheCall);
 public:
   enum FormatStringType {
 FST_Scanf,
Index: test/Preprocessor/aarch64-target-features.c
===
--- test/Preprocessor/aarch64-target-features.c
+++ test/Preprocessor/aarch64-target-features.c
@@ -316,3 +316,6 @@
 // CHECK-V81A-FEATURE-2: "-cc1"{{.*}} "-triple" "aarch64{{.*}}" "-target-feature" "+neon" "-target-feature" "+v8.1a" "-target-feature" "-crypto"
 // CHECK-V81A-FEATURE-3: "-cc1"{{.*}} "-triple" "aarch64{{.*}}" "-target-feature" "+v8.1a" "-target-feature" "-neon"
 
+// == Check Memory Tagging Extensions (MTE).
+// RUN: %clang -target arm64-none-linux-gnu -march=armv8.5-a+memtag -x c -E -dM %s -o - 2>&1 | FileCheck -check-prefix=CHECK-MEMTAG %s
+// CHECK-MEMTAG: __ARM_FEATURE_MEMORY_TAGGING 1
Index: test/Sema/builtins-arm64-mte.c
===
--- test/Sema/builtins-arm64-mte.c
+++ test/Sema/builtins-arm64-mte.c
@@ -0,0 +1,136 @@
+// RUN: %clang_cc1 -triple arm64-arm-eabi %s -target-feature +mte -fsyntax-only -verify
+// RUN: %clang_cc1 -triple arm64-arm-eabi %s -target-feature +mte -x c++ -fsyntax-only -verify
+#include 
+#include 
+
+int  *create_tag1(int a, unsigned b) {
+  // expected-error@+1 {{first argument of MTE builtin function must be a pointer ('int' invalid)}}
+  return __arm_mte_create_random_tag(a,b);
+}
+
+int  *create_tag2(int *a, unsigned *b) {
+  // expected-error@+1 {{second argument of MTE builtin function must be an integer type ('unsigned int *' invalid)}}
+  return __arm_mte_create_random_tag(a,b);
+}
+
+int  *create_tag3(const int *a, unsigned b) {
+#ifdef __cplusplus
+  // expected-error@+1 {{cannot initialize return object of type 'int *' with an rvalue of type 'const int *'}}
+  return __arm_mte_create_random_tag(a,b);
+#else
+  

[PATCH] D60485: [AArch64] Add support for MTE intrinsics

2019-04-25 Thread Javed Absar via Phabricator via cfe-commits
javed.absar marked an inline comment as done.
javed.absar added inline comments.



Comment at: lib/CodeGen/CGBuiltin.cpp:7129-7131
+// Although it is possible to supply a different return
+// address (first arg) to this intrinsic, for now we set
+// return address same as input address.

t.p.northover wrote:
> I think this should be fixed now.  It looks like technical debt from the fact 
> that the instructions only fairly recently gained that feature after the 
> intrinsics were implemented internally. There's no good way to justify the 
> current semantics to someone unaware of that history.
Not quite that really.  So the instruction did gain the feature recently like 
you mentioned. But the ACLE/intrinsics were designed and agreed upon after it 
and it was decided in ACLE discussions that the exta feature added complexity 
that need not be exposed at ACLE level yet. No big use case to justify 
complicating the ACLE MTE spec yet. Directly assembly can use that instruction 
though.


CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D60485/new/

https://reviews.llvm.org/D60485



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D60485: [AArch64] Add support for MTE intrinsics

2019-04-23 Thread Javed Absar via Phabricator via cfe-commits
javed.absar updated this revision to Diff 196297.
javed.absar marked an inline comment as done.
javed.absar added a comment.

Hi Tim:
Have made the changes as suggested. Please have a look.


CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D60485/new/

https://reviews.llvm.org/D60485

Files:
  include/clang/Basic/BuiltinsAArch64.def
  include/clang/Basic/DiagnosticSemaKinds.td
  include/clang/Sema/Sema.h
  lib/Basic/Targets/AArch64.cpp
  lib/Basic/Targets/AArch64.h
  lib/CodeGen/CGBuiltin.cpp
  lib/Headers/arm_acle.h
  lib/Sema/SemaChecking.cpp
  test/CodeGen/arm64-mte.c
  test/Preprocessor/aarch64-target-features.c
  test/Sema/builtins-arm64-mte.c

Index: test/Sema/builtins-arm64-mte.c
===
--- /dev/null
+++ test/Sema/builtins-arm64-mte.c
@@ -0,0 +1,136 @@
+// RUN: %clang_cc1 -triple arm64-arm-eabi %s -target-feature +mte -fsyntax-only -verify
+// RUN: %clang_cc1 -triple arm64-arm-eabi %s -target-feature +mte -x c++ -fsyntax-only -verify
+#include 
+#include 
+
+int  *create_tag1(int a, unsigned b) {
+  // expected-error@+1 {{first argument of MTE builtin function must be a pointer ('int' invalid)}}
+  return __arm_mte_create_random_tag(a,b);
+}
+
+int  *create_tag2(int *a, unsigned *b) {
+  // expected-error@+1 {{second argument of MTE builtin function must be an integer type ('unsigned int *' invalid)}}
+  return __arm_mte_create_random_tag(a,b);
+}
+
+int  *create_tag3(const int *a, unsigned b) {
+#ifdef __cplusplus
+  // expected-error@+1 {{cannot initialize return object of type 'int *' with an rvalue of type 'const int *'}}
+  return __arm_mte_create_random_tag(a,b);
+#else
+  // expected-warning@+1 {{returning 'const int *' from a function with result type 'int *' discards qualifiers}}
+  return __arm_mte_create_random_tag(a,b);
+#endif
+}
+
+int  *create_tag4(volatile int *a, unsigned b) {
+#ifdef __cplusplus
+  // expected-error@+1 {{cannot initialize return object of type 'int *' with an rvalue of type 'volatile int *'}}
+  return __arm_mte_create_random_tag(a,b);
+#else
+  // expected-warning@+1 {{returning 'volatile int *' from a function with result type 'int *' discards qualifiers}}
+  return __arm_mte_create_random_tag(a,b);
+#endif
+}
+
+int  *increment_tag1(int *a, unsigned b) {
+  // expected-error@+1 {{argument to '__builtin_arm_addg' must be a constant integer}}
+  return __arm_mte_increment_tag(a,b);
+}
+
+int  *increment_tag2(int *a) {
+  // expected-error@+1 {{argument value 16 is outside the valid range [0, 15]}}
+  return __arm_mte_increment_tag(a,16);
+}
+
+int  *increment_tag3(int *a) {
+  // expected-error@+1 {{argument value -1 is outside the valid range [0, 15]}}
+  return __arm_mte_increment_tag(a,-1);
+}
+
+int  *increment_tag4(const int *a) {
+#ifdef __cplusplus
+  // expected-error@+1 {{cannot initialize return object of type 'int *' with an rvalue of type 'const int *'}}
+  return __arm_mte_increment_tag(a,5);
+#else
+  // expected-warning@+1 {{returning 'const int *' from a function with result type 'int *' discards qualifiers}}
+  return __arm_mte_increment_tag(a,5);
+#endif
+}
+
+int *increment_tag5(const volatile int *a) {
+#ifdef __cplusplus
+  // expected-error@+1 {{cannot initialize return object of type 'int *' with an rvalue of type 'const volatile int *'}}
+  return __arm_mte_increment_tag(a,5);
+#else
+  // expected-warning@+1 {{returning 'const volatile int *' from a function with result type 'int *' discards qualifiers}}
+  return __arm_mte_increment_tag(a,5);
+#endif
+}
+
+unsigned exclude_tag1(int *ptr, unsigned m) {
+   // expected-error@+1 {{first argument of MTE builtin function must be a pointer ('int' invalid)}}
+   return  __arm_mte_exclude_tag(*ptr, m);
+}
+
+unsigned exclude_tag2(int *ptr, int *m) {
+   // expected-error@+1 {{second argument of MTE builtin function must be an integer type ('int *' invalid)}}
+   return  __arm_mte_exclude_tag(ptr, m);
+}
+
+void get_tag1() {
+   // expected-error@+1 {{too few arguments to function call, expected 1, have 0}}
+   __arm_mte_get_tag();
+}
+
+int *get_tag2(int ptr) {
+   // expected-error@+1 {{first argument of MTE builtin function must be a pointer ('int' invalid)}}
+   return __arm_mte_get_tag(ptr);
+}
+
+int *get_tag3(const volatile int *ptr) {
+#ifdef __cplusplus
+  // expected-error@+1 {{cannot initialize return object of type 'int *' with an rvalue of type 'const volatile int *'}}
+  return __arm_mte_get_tag(ptr);
+#else
+  // expected-warning@+1 {{returning 'const volatile int *' from a function with result type 'int *' discards qualifiers}}
+  return __arm_mte_get_tag(ptr);
+#endif
+}
+
+void set_tag1() {
+   // expected-error@+1 {{too few arguments to function call, expected 1, have 0}}
+   __arm_mte_set_tag();
+}
+
+void set_tag2(int ptr) {
+   // expected-error@+1 {{first argument of MTE builtin function must be a pointer ('int' invalid)}}
+   __arm_mte_set_tag(ptr);
+}
+
+ptrdiff_t subtract_pointers1(int a, int *b) {
+  // 

[PATCH] D60485: [AArch64] Add support for MTE intrinsics

2019-04-15 Thread Javed Absar via Phabricator via cfe-commits
javed.absar marked 2 inline comments as done.
javed.absar added inline comments.



Comment at: include/clang/Basic/DiagnosticSemaKinds.td:9566
+def err_memtag_arg_null_or_pointer : Error<
+  "%0 argument must be a null or a pointer (%1 invalid)">;
+def err_memtag_any2arg_pointer : Error<

t.p.northover wrote:
> I think these diagnostics could do with a bit more context for consistency. 
> They seem to take "MTE builtin" for granted, whereas most Clang messages 
> mention what they're talking about.
> 
> I'm not saying "MTE builtin" is the best we can come up with, BTW, just that 
> something more would be nice.
I thought of doing that too , so can prefix these warnings with 'mte builtin' 
if that's what you meant. But the intrinsic called kind of names same thing 
(__arm_mte_..).



Comment at: lib/Headers/arm_acle.h:610-615
+#define __arm_mte_create_random_tag(__ptr, __mask)  __builtin_arm_irg(__ptr, 
__mask)
+#define __arm_mte_increment_tag(__ptr, __tag_offset)  
__builtin_arm_addg(__ptr, __tag_offset)
+#define __arm_mte_exclude_tag(__ptr, __excluded)  __builtin_arm_gmi(__ptr, 
__excluded)
+#define __arm_mte_get_tag(__ptr) __builtin_arm_ldg(__ptr)
+#define __arm_mte_set_tag(__ptr) __builtin_arm_stg(__ptr)
+#define __arm_mte_ptrdiff(__ptra, __ptrb) __builtin_arm_subp(__ptra, __ptrb)

t.p.northover wrote:
> Why are the builtin names so different from the ones exposed. GCC 
> compatibility? LLVM?
The builtin name (e.g. _mte_irg) is reflecting the instruction that implements 
the otherwise meaningful ACLE names  (mte_create_tag). Its just that the 
instruction names are sometimes cryptic (e.g. stg, ldg). I could change the 
names to __builtin_arm_create_tag etc and push the meaningful name -> insn 
level name to intrinsic level or further down but that would mean lots of name 
changes to current patch and tests. 


CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D60485/new/

https://reviews.llvm.org/D60485



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D60485: [AArch64] Add support for MTE intrinsics

2019-04-15 Thread Javed Absar via Phabricator via cfe-commits
javed.absar updated this revision to Diff 195112.
javed.absar added a comment.

Tests merged as suggested.


CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D60485/new/

https://reviews.llvm.org/D60485

Files:
  include/clang/Basic/BuiltinsAArch64.def
  include/clang/Basic/DiagnosticSemaKinds.td
  include/clang/Sema/Sema.h
  lib/Basic/Targets/AArch64.cpp
  lib/Basic/Targets/AArch64.h
  lib/CodeGen/CGBuiltin.cpp
  lib/Headers/arm_acle.h
  lib/Sema/SemaChecking.cpp
  test/CodeGen/arm64-mte.c
  test/Preprocessor/aarch64-target-features.c
  test/Sema/builtins-arm64-mte.c

Index: test/Sema/builtins-arm64-mte.c
===
--- /dev/null
+++ test/Sema/builtins-arm64-mte.c
@@ -0,0 +1,136 @@
+// RUN: %clang_cc1 -triple arm64-arm-eabi %s -target-feature +mte -fsyntax-only -verify
+// RUN: %clang_cc1 -triple arm64-arm-eabi %s -target-feature +mte -x c++ -fsyntax-only -verify
+#include 
+#include 
+
+int  *create_tag1(int a, unsigned b) {
+  // expected-error@+1 {{first argument must be a pointer ('int' invalid)}}
+  return __arm_mte_create_random_tag(a,b);
+}
+
+int  *create_tag2(int *a, unsigned *b) {
+  // expected-error@+1 {{second argument must be an integer type ('unsigned int *' invalid)}}
+  return __arm_mte_create_random_tag(a,b);
+}
+
+int  *create_tag3(const int *a, unsigned b) {
+#ifdef __cplusplus
+  // expected-error@+1 {{cannot initialize return object of type 'int *' with an rvalue of type 'const int *'}}
+  return __arm_mte_create_random_tag(a,b);
+#else
+  // expected-warning@+1 {{returning 'const int *' from a function with result type 'int *' discards qualifiers}}
+  return __arm_mte_create_random_tag(a,b);
+#endif
+}
+
+int  *create_tag4(volatile int *a, unsigned b) {
+#ifdef __cplusplus
+  // expected-error@+1 {{cannot initialize return object of type 'int *' with an rvalue of type 'volatile int *'}}
+  return __arm_mte_create_random_tag(a,b);
+#else
+  // expected-warning@+1 {{returning 'volatile int *' from a function with result type 'int *' discards qualifiers}}
+  return __arm_mte_create_random_tag(a,b);
+#endif
+}
+
+int  *increment_tag1(int *a, unsigned b) {
+  // expected-error@+1 {{argument to '__builtin_arm_addg' must be a constant integer}}
+  return __arm_mte_increment_tag(a,b);
+}
+
+int  *increment_tag2(int *a) {
+  // expected-error@+1 {{argument value 16 is outside the valid range [0, 15]}}
+  return __arm_mte_increment_tag(a,16);
+}
+
+int  *increment_tag3(int *a) {
+  // expected-error@+1 {{argument value -1 is outside the valid range [0, 15]}}
+  return __arm_mte_increment_tag(a,-1);
+}
+
+int  *increment_tag4(const int *a) {
+#ifdef __cplusplus
+  // expected-error@+1 {{cannot initialize return object of type 'int *' with an rvalue of type 'const int *'}}
+  return __arm_mte_increment_tag(a,5);
+#else
+  // expected-warning@+1 {{returning 'const int *' from a function with result type 'int *' discards qualifiers}}
+  return __arm_mte_increment_tag(a,5);
+#endif
+}
+
+int *increment_tag5(const volatile int *a) {
+#ifdef __cplusplus
+  // expected-error@+1 {{cannot initialize return object of type 'int *' with an rvalue of type 'const volatile int *'}}
+  return __arm_mte_increment_tag(a,5);
+#else
+  // expected-warning@+1 {{returning 'const volatile int *' from a function with result type 'int *' discards qualifiers}}
+  return __arm_mte_increment_tag(a,5);
+#endif
+}
+
+unsigned exclude_tag1(int *ptr, unsigned m) {
+   // expected-error@+1 {{first argument must be a pointer ('int' invalid)}}
+   return  __arm_mte_exclude_tag(*ptr, m);
+}
+
+unsigned exclude_tag2(int *ptr, int *m) {
+   // expected-error@+1 {{second argument must be an integer type ('int *' invalid)}}
+   return  __arm_mte_exclude_tag(ptr, m);
+}
+
+void get_tag1() {
+   // expected-error@+1 {{too few arguments to function call, expected 1, have 0}}
+   __arm_mte_get_tag();
+}
+
+int *get_tag2(int ptr) {
+   // expected-error@+1 {{first argument must be a pointer ('int' invalid)}}
+   return __arm_mte_get_tag(ptr);
+}
+
+int *get_tag3(const volatile int *ptr) {
+#ifdef __cplusplus
+  // expected-error@+1 {{cannot initialize return object of type 'int *' with an rvalue of type 'const volatile int *'}}
+  return __arm_mte_get_tag(ptr);
+#else
+  // expected-warning@+1 {{returning 'const volatile int *' from a function with result type 'int *' discards qualifiers}}
+  return __arm_mte_get_tag(ptr);
+#endif
+}
+
+void set_tag1() {
+   // expected-error@+1 {{too few arguments to function call, expected 1, have 0}}
+   __arm_mte_set_tag();
+}
+
+void set_tag2(int ptr) {
+   // expected-error@+1 {{first argument must be a pointer ('int' invalid)}}
+   __arm_mte_set_tag(ptr);
+}
+
+ptrdiff_t subtract_pointers1(int a, int *b) {
+  // expected-error@+1 {{first argument must be a null or a pointer ('int' invalid)}}
+  return __arm_mte_ptrdiff(a, b);
+}
+
+ptrdiff_t subtract_pointers2(int *a, int b) {
+  // expected-error@+1 {{second argument must be a null or 

[PATCH] D60485: [AArch64] Add support for MTE intrinsics

2019-04-09 Thread Javed Absar via Phabricator via cfe-commits
javed.absar created this revision.
javed.absar added reviewers: DavidSpickett, olista01.
Herald added a subscriber: kristof.beyls.

This patch provides intrinsics support for Memory Tagging Extension (MTE),

  which was introduced with the Armv8.5-a architecture.

These intrinsics are available when __ARM_FEATURE_MEMORY_TAGGING is defined.
Each intrinsic is described in detail in   the latest ACLE Q1 2019 
documentation:

  https://developer.arm.com/docs/101028/latest

However, below we also list the intrinsics:

1. T* __arm_mte_create_random_tag(T* src, uint64_t mask); This intrinsic 
returns a pointer containing a randomly created logical address tag.
2. T* __arm_mte_increment_tag(T* src, unsigned offset); This intrinsic returns 
a pointer which is a copy of the input pointer src but with the logical address 
tag part offset by a specified offset value.
3. uint64_t __arm_mte_exclude_tag(T* src, uint64_t excluded); This intrinsic 
adds a logical tag to the set of excluded logical tags.
4. void __arm_mte_set_tag(T* tag_address); This intrinsic stores an allocation 
tag, computed from the logical tag, to the tag memory thereby setting the 
allocation tag for the 16-byte granule of memory.
5. T* __arm_mte_get_tag(T* address); This intrinsic loads the allocation tag 
from tag memory and returns the corresponding logical tag as part of the 
returned pointer value.
6. ptrdiff_t __arm_mte_ptrdiff(T* a, T* b); The intrinsic calculates the 
difference between the address parts of the two pointers, ignoring the tags.


https://reviews.llvm.org/D60485

Files:
  include/clang/Basic/BuiltinsAArch64.def
  include/clang/Basic/DiagnosticSemaKinds.td
  include/clang/Sema/Sema.h
  lib/Basic/Targets/AArch64.cpp
  lib/Basic/Targets/AArch64.h
  lib/CodeGen/CGBuiltin.cpp
  lib/Headers/arm_acle.h
  lib/Sema/SemaChecking.cpp
  test/CodeGen/arm64-mte.c
  test/Preprocessor/aarch64-target-features.c
  test/Sema/builtins-arm64-mte.c
  test/Sema/builtins-arm64-mte2.cpp

Index: test/Sema/builtins-arm64-mte2.cpp
===
--- /dev/null
+++ test/Sema/builtins-arm64-mte2.cpp
@@ -0,0 +1,8 @@
+// RUN: %clang_cc1 -triple arm64-arm-eabi %s -target-feature +mte -x c++ -fsyntax-only -verify
+#include 
+#include 
+
+ptrdiff_t subtract_pointers() {
+  // expected-error@+1 {{at least one argument must be a pointer ('nullptr_t', 'nullptr_t' invalid)}}
+  return __arm_mte_ptrdiff(nullptr, nullptr);
+}
Index: test/Sema/builtins-arm64-mte.c
===
--- /dev/null
+++ test/Sema/builtins-arm64-mte.c
@@ -0,0 +1,129 @@
+// RUN: %clang_cc1 -triple arm64-arm-eabi %s -target-feature +mte -fsyntax-only -verify
+// RUN: %clang_cc1 -triple arm64-arm-eabi %s -target-feature +mte -x c++ -fsyntax-only -verify
+#include 
+#include 
+
+int  *create_tag1(int a, unsigned b) {
+  // expected-error@+1 {{first argument must be a pointer ('int' invalid)}}
+  return __arm_mte_create_random_tag(a,b);
+}
+
+int  *create_tag2(int *a, unsigned *b) {
+  // expected-error@+1 {{second argument must be an integer type ('unsigned int *' invalid)}}
+  return __arm_mte_create_random_tag(a,b);
+}
+
+int  *create_tag3(const int *a, unsigned b) {
+#ifdef __cplusplus
+  // expected-error@+1 {{cannot initialize return object of type 'int *' with an rvalue of type 'const int *'}}
+  return __arm_mte_create_random_tag(a,b);
+#else
+  // expected-warning@+1 {{returning 'const int *' from a function with result type 'int *' discards qualifiers}}
+  return __arm_mte_create_random_tag(a,b);
+#endif
+}
+
+int  *create_tag4(volatile int *a, unsigned b) {
+#ifdef __cplusplus
+  // expected-error@+1 {{cannot initialize return object of type 'int *' with an rvalue of type 'volatile int *'}}
+  return __arm_mte_create_random_tag(a,b);
+#else
+  // expected-warning@+1 {{returning 'volatile int *' from a function with result type 'int *' discards qualifiers}}
+  return __arm_mte_create_random_tag(a,b);
+#endif
+}
+
+int  *increment_tag1(int *a, unsigned b) {
+  // expected-error@+1 {{argument to '__builtin_arm_addg' must be a constant integer}}
+  return __arm_mte_increment_tag(a,b);
+}
+
+int  *increment_tag2(int *a) {
+  // expected-error@+1 {{argument value 16 is outside the valid range [0, 15]}}
+  return __arm_mte_increment_tag(a,16);
+}
+
+int  *increment_tag3(int *a) {
+  // expected-error@+1 {{argument value -1 is outside the valid range [0, 15]}}
+  return __arm_mte_increment_tag(a,-1);
+}
+
+int  *increment_tag4(const int *a) {
+#ifdef __cplusplus
+  // expected-error@+1 {{cannot initialize return object of type 'int *' with an rvalue of type 'const int *'}}
+  return __arm_mte_increment_tag(a,5);
+#else
+  // expected-warning@+1 {{returning 'const int *' from a function with result type 'int *' discards qualifiers}}
+  return __arm_mte_increment_tag(a,5);
+#endif
+}
+
+int *increment_tag5(const volatile int *a) {
+#ifdef __cplusplus
+  // expected-error@+1 {{cannot 

[PATCH] D59879: [ARM][CMSE] Add commandline option and feature macro

2019-03-27 Thread Javed Absar via Phabricator via cfe-commits
javed.absar created this revision.
javed.absar added a reviewer: dmgreen.
Herald added a subscriber: kristof.beyls.
Herald added a project: clang.

This is first in series of patches following the RFC 
http://lists.llvm.org/pipermail/cfe-dev/2019-March/061834.html informing the 
community about providing CMSE support in clang/llvm.

This is patch C1 (as mentioned in the RFC).

It defines macro __ARM_FEATURE_CMSE to 1 for v8-M targets and introduces -mcmse 
option which for v8-M targets sets __ARM_FEATURE_CMSE to 3.   A diagnostic is 
produced when the option is given on architectures without support for Security 
Extensions.


Repository:
  rC Clang

https://reviews.llvm.org/D59879

Files:
  include/clang/Basic/Attr.td
  include/clang/Basic/DiagnosticCommonKinds.td
  include/clang/Basic/LangOptions.def
  include/clang/Driver/Options.td
  lib/Basic/Targets/ARM.cpp
  lib/Driver/ToolChains/Arch/ARM.cpp
  lib/Driver/ToolChains/Clang.cpp
  lib/Frontend/CompilerInvocation.cpp
  test/Preprocessor/arm-target-features.c

Index: test/Preprocessor/arm-target-features.c
===
--- test/Preprocessor/arm-target-features.c
+++ test/Preprocessor/arm-target-features.c
@@ -198,6 +198,7 @@
 // V8M_BASELINE: #define __ARM_ARCH_ISA_THUMB 1
 // V8M_BASELINE: #define __ARM_ARCH_PROFILE 'M'
 // V8M_BASELINE-NOT: __ARM_FEATURE_CRC32
+// V8M_BASELINE: #define __ARM_FEATURE_CMSE 1
 // V8M_BASELINE-NOT: __ARM_FEATURE_DSP
 // V8M_BASELINE-NOT: __ARM_FP 0x{{.*}}
 // V8M_BASELINE-NOT: __GCC_HAVE_SYNC_COMPARE_AND_SWAP_1
@@ -210,6 +211,7 @@
 // V8M_MAINLINE: #define __ARM_ARCH_ISA_THUMB 2
 // V8M_MAINLINE: #define __ARM_ARCH_PROFILE 'M'
 // V8M_MAINLINE-NOT: __ARM_FEATURE_CRC32
+// V8M_MAINLINE: #define __ARM_FEATURE_CMSE 1
 // V8M_MAINLINE-NOT: __ARM_FEATURE_DSP
 // V8M_MAINLINE-NOT: #define __ARM_FP 0x
 // V8M_MAINLINE: #define __GCC_HAVE_SYNC_COMPARE_AND_SWAP_1 1
@@ -675,6 +677,24 @@
 // M7-THUMB-ALLOW-FP-INSTR:#define __ARM_FP 0xe
 // M7-THUMB-ALLOW-FP-INSTR:#define __ARM_FPV5__ 1
 
+// Check that -mcmse (security extension) option works correctly for v8-M targets
+// RUN: %clang -target armv8m.base-none-linux-gnu -mcmse -x c -E -dM %s -o - | FileCheck -match-full-lines --check-prefix=V8M_CMSE %s
+// RUN: %clang -target armv8m.main-none-linux-gnu -mcmse -x c -E -dM %s -o - | FileCheck -match-full-lines --check-prefix=V8M_CMSE %s
+// RUN: %clang -target arm-none-linux-gnu -mcpu=cortex-m33 -mcmse -x c -E -dM %s -o - | FileCheck -match-full-lines --check-prefix=V8M_CMSE %s
+// RUN: %clang -target arm -mcpu=cortex-m23 -mcmse -x c -E -dM %s -o - | FileCheck -match-full-lines --check-prefix=V8M_CMSE %s
+// V8M_CMSE-NOT: __ARM_FEATURE_CMSE 1
+// V8M_CMSE: #define __ARM_FEATURE_CMSE 3
+
+// Check that CMSE is not defined on architectures w/o support for security extension
+// RUN: %clang -target arm-arm-none-gnueabi -mcpu=cortex-a5 -x c -E -dM %s -o - | FileCheck -match-full-lines --check-prefix=NOTV8M_CMSE %s
+// RUN: %clang -target armv8a-none-linux-gnu -x c -E -dM %s -o - | FileCheck -match-full-lines --check-prefix=NOTV8M_CMSE %s
+// RUN: %clang -target armv8.1a-none-none-eabi -x c -E -dM %s -o - | FileCheck -match-full-lines --check-prefix=NOTV8M_CMSE %s
+// NOTV8M_CMSE-NOT: __ARM_FEATURE_CMSE
+
+// Check that -mcmse option gives error on non v8-M targets
+// RUN: not %clang -target arm-arm-none-eabi -mthumb -mcmse -mcpu=cortex-m7 -x c -E -dM %s -o - 2>&1 | FileCheck -match-full-lines --check-prefix=NOTV8MCMSE_OPT %s
+// NOTV8MCMSE_OPT: error: -mcmse is not supported for cortex-m7
+
 // Test whether predefines are as expected when targeting v8m cores
 // RUN: %clang -target arm -mcpu=cortex-m23 -x c -E -dM %s -o - | FileCheck -match-full-lines --check-prefix=M23 %s
 // M23: #define __ARM_ARCH 8
Index: lib/Frontend/CompilerInvocation.cpp
===
--- lib/Frontend/CompilerInvocation.cpp
+++ lib/Frontend/CompilerInvocation.cpp
@@ -2702,6 +2702,7 @@
   Opts.HalfArgsAndReturns = Args.hasArg(OPT_fallow_half_arguments_and_returns)
 | Opts.NativeHalfArgsAndReturns;
   Opts.GNUAsm = !Args.hasArg(OPT_fno_gnu_inline_asm);
+  Opts.Cmse = Args.hasArg(OPT_mcmse); // CMSE
 
   // __declspec is enabled by default for the PS4 by the driver, and also
   // enabled for Microsoft Extensions or Borland Extensions, here.
Index: lib/Driver/ToolChains/Clang.cpp
===
--- lib/Driver/ToolChains/Clang.cpp
+++ lib/Driver/ToolChains/Clang.cpp
@@ -1386,6 +1386,10 @@
   if (!Args.hasFlag(options::OPT_mimplicit_float,
 options::OPT_mno_implicit_float, true))
 CmdArgs.push_back("-no-implicit-float");
+
+  if (Args.getLastArg(options::OPT_mcmse)) {
+CmdArgs.push_back("-mcmse");
+  }
 }
 
 void Clang::RenderTargetOptions(const llvm::Triple ,
Index: lib/Driver/ToolChains/Arch/ARM.cpp

[PATCH] D51429: [AArch64] Return Address Signing B Key Support

2018-10-01 Thread Javed Absar via Phabricator via cfe-commits
javed.absar added inline comments.



Comment at: include/clang/Frontend/CodeGenOptions.h:117
 
+  enum SignReturnAddressKeyValue { AKey, BKey };
+

Perhaps a line of comment on each enum-value would be useful (much like the 
code around).


https://reviews.llvm.org/D51429



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D49793: [AArch64] - return address signing

2018-07-25 Thread Javed Absar via Phabricator via cfe-commits
javed.absar added a comment.

Maybe you can provide some more context to this patch (why you need this, or 
point to some document), if possible.




Comment at: include/clang/Frontend/CodeGenOptions.h:111
 
+  enum SignReturnAddressScope { None, Partial, All };
+

Please conform this to the code around (i.e. each option on a separate line 
with comments explaining the option).



Comment at: test/CodeGen/aarch64-sign-return-address.c:5
+
+// NONE: @foo() #[[ATTR:[0-9]*]]
+// NONE-NOT: attributes #[[ATTR]] = { {{.*}} "sign-return-address"={{.*}} }

Can the label check not be under one 'CHECK' prefix? 


Repository:
  rC Clang

https://reviews.llvm.org/D49793



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D37454: [coroutines] Make sure auto return type of await_resume is properly handled

2017-09-05 Thread Javed Absar via Phabricator via cfe-commits
javed.absar added inline comments.



Comment at: test/SemaCXX/coroutines.cpp:169
+void check_auto_await_suspend() {
+  co_await auto_await_suspend{}; // OK
+}

maybe change the comment to something more meaningful, or remove it.


https://reviews.llvm.org/D37454



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D30326: [MS-ABI] Allow #pragma section to choose for ZI data

2017-06-22 Thread Javed Absar via Phabricator via cfe-commits
javed.absar abandoned this revision.
javed.absar added a comment.

Abandoning as there is a separate pragma clang section implementation now.


https://reviews.llvm.org/D30326



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D33412: Add support for #pragma clang section

2017-06-05 Thread Javed Absar via Phabricator via cfe-commits
This revision was automatically updated to reflect the committed changes.
Closed by commit rL304705: Add support for #pragma clang section (authored by 
javed.absar).

Changed prior to commit:
  https://reviews.llvm.org/D33412?vs=100846=101383#toc

Repository:
  rL LLVM

https://reviews.llvm.org/D33412

Files:
  cfe/trunk/docs/LanguageExtensions.rst
  cfe/trunk/include/clang/Basic/Attr.td
  cfe/trunk/include/clang/Basic/DiagnosticParseKinds.td
  cfe/trunk/include/clang/Parse/Parser.h
  cfe/trunk/include/clang/Sema/Sema.h
  cfe/trunk/lib/CodeGen/CGDecl.cpp
  cfe/trunk/lib/CodeGen/CodeGenModule.cpp
  cfe/trunk/lib/Parse/ParsePragma.cpp
  cfe/trunk/lib/Sema/SemaAttr.cpp
  cfe/trunk/lib/Sema/SemaDecl.cpp
  cfe/trunk/test/CodeGenCXX/clang-sections-tentative.c
  cfe/trunk/test/CodeGenCXX/clang-sections.cpp
  cfe/trunk/test/Sema/pragma-clang-section.c

Index: cfe/trunk/docs/LanguageExtensions.rst
===
--- cfe/trunk/docs/LanguageExtensions.rst
+++ cfe/trunk/docs/LanguageExtensions.rst
@@ -2521,3 +2521,45 @@
 The attributes are applied to all matching declarations individually, even when
 the attribute is semantically incorrect. The attributes that aren't applied to
 any declaration are not verified semantically.
+
+Specifying section names for global objects (#pragma clang section)
+===
+
+The ``#pragma clang section`` directive provides a means to assign section-names
+to global variables, functions and static variables.
+
+The section names can be specified as:
+
+.. code-block:: c++
+
+  #pragma clang section bss="myBSS" data="myData" rodata="myRodata" text="myText"
+
+The section names can be reverted back to default name by supplying an empty
+string to the section kind, for example:
+
+.. code-block:: c++
+
+  #pragma clang section bss="" data="" text="" rodata=""
+
+The ``#pragma clang section`` directive obeys the following rules:
+
+* The pragma applies to all global variable, statics and function declarations
+  from the pragma to the end of the translation unit.
+
+* The pragma clang section is enabled automatically, without need of any flags.
+
+* This feature is only defined to work sensibly for ELF targets.
+
+* If section name is specified through _attribute_((section("myname"))), then
+  the attribute name gains precedence.
+
+* Global variables that are initialized to zero will be placed in the named
+  bss section, if one is present.
+
+* The ``#pragma clang section`` directive does not does try to infer section-kind
+  from the name. For example, naming a section "``.bss.mySec``" does NOT mean
+  it will be a bss section name.
+
+* The decision about which section-kind applies to each global is taken in the back-end.
+  Once the section-kind is known, appropriate section name, as specified by the user using
+  ``#pragma clang section`` directive, is applied to that global.
Index: cfe/trunk/include/clang/Basic/DiagnosticParseKinds.td
===
--- cfe/trunk/include/clang/Basic/DiagnosticParseKinds.td
+++ cfe/trunk/include/clang/Basic/DiagnosticParseKinds.td
@@ -887,9 +887,18 @@
   "missing ')' after '#pragma %0' - ignoring">, InGroup;
 def warn_pragma_expected_identifier : Warning<
   "expected identifier in '#pragma %0' - ignored">, InGroup;
+
+// '#pragma clang section' related errors
+def err_pragma_expected_clang_section_name : Error<
+  "expected one of [bss|data|rodata|text] section kind in '#pragma %0'">;
+def err_pragma_clang_section_expected_equal : Error<
+  "expected '=' following '#pragma clang section %select{invalid|bss|data|rodata|text}0'">;
+def err_pragma_clang_section_expected_name_or_clear : Error<
+  "expected section name or '\"\"' following '#pragma clang section %select{invalid|bss|data|rodata|text}0'">;
 def warn_pragma_expected_section_name : Warning<
   "expected a string literal for the section name in '#pragma %0' - ignored">,
   InGroup;
+
 def warn_pragma_expected_section_push_pop_or_name : Warning<
   "expected push, pop or a string literal for the section name in '#pragma %0' - ignored">,
   InGroup;
Index: cfe/trunk/include/clang/Basic/Attr.td
===
--- cfe/trunk/include/clang/Basic/Attr.td
+++ cfe/trunk/include/clang/Basic/Attr.td
@@ -1683,6 +1683,42 @@
   let Documentation = [SectionDocs];
 }
 
+def PragmaClangBSSSection : InheritableAttr {
+  // This attribute has no spellings as it is only ever created implicitly.
+  let Spellings = [];
+  let Args = [StringArgument<"Name">];
+  let Subjects = SubjectList<[GlobalVar], ErrorDiag,
+ "ExpectedFunctionMethodOrGlobalVar">;
+  let Documentation = [Undocumented];
+}
+
+def PragmaClangDataSection : InheritableAttr {
+  // This attribute has no spellings as it is only ever created implicitly.
+  let Spellings = [];
+  let Args = 

[PATCH] D33719: Add _Float16 as a C/C++ source language type

2017-05-31 Thread Javed Absar via Phabricator via cfe-commits
javed.absar added inline comments.



Comment at: include/clang/Sema/DeclSpec.h:283
   static const TST TST_double = clang::TST_double;
+  static const TST TST_Float16 = clang::TST_Float16;
   static const TST TST_float128 = clang::TST_float128;

Any particular reason why its not "TST_float16" ?


https://reviews.llvm.org/D33719



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D33721: [ARM] Add support for target("arm") and target("thumb").

2017-05-31 Thread Javed Absar via Phabricator via cfe-commits
javed.absar added a comment.






Comment at: include/clang/Basic/Attr.td:1774
+
+// Convert GNU target names for arm and thumb to thumb-mode target
+// feature.

Would this be a more accurate comment:

"...arm and thumb to thumb-mode" => "arm and thumb to arm-mode or thumb-mode, 
respectively"
Or 
"[-|+] thumb-mode"


https://reviews.llvm.org/D33721



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D33412: Add support for #pragma clang section

2017-05-31 Thread Javed Absar via Phabricator via cfe-commits
javed.absar updated this revision to Diff 100846.
javed.absar added a comment.
Herald added a subscriber: kristof.beyls.

Thanks Roger for the review and the suggestion to add documentation in 
LanguageExtensions.rst.  I have done so now.
--Javed


https://reviews.llvm.org/D33412

Files:
  docs/LanguageExtensions.rst
  include/clang/Basic/Attr.td
  include/clang/Basic/DiagnosticParseKinds.td
  include/clang/Parse/Parser.h
  include/clang/Sema/Sema.h
  lib/CodeGen/CGDecl.cpp
  lib/CodeGen/CodeGenModule.cpp
  lib/Parse/ParsePragma.cpp
  lib/Sema/SemaAttr.cpp
  lib/Sema/SemaDecl.cpp
  test/CodeGenCXX/clang-sections-tentative.c
  test/CodeGenCXX/clang-sections.cpp
  test/Sema/pragma-clang-section.c

Index: test/Sema/pragma-clang-section.c
===
--- /dev/null
+++ test/Sema/pragma-clang-section.c
@@ -0,0 +1,17 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s -triple arm-none-eabi
+#pragma clang section bss="mybss.1" data="mydata.1" rodata="myrodata.1" text="mytext.1"
+#pragma clang section bss="" data="" rodata="" text=""
+#pragma clang section
+
+#pragma clang section dss="mybss.2" // expected-error {{expected one of [bss|data|rodata|text] section kind in '#pragma clang section'}}
+#pragma clang section deta="mydata.2" // expected-error {{expected one of [bss|data|rodata|text] section kind in '#pragma clang section'}}
+#pragma clang section rodeta="rodata.2" // expected-error {{expected one of [bss|data|rodata|text] section kind in '#pragma clang section'}}
+#pragma clang section taxt="text.2" // expected-error {{expected one of [bss|data|rodata|text] section kind in '#pragma clang section'}}
+
+#pragma clang section section bss="mybss.2"  // expected-error {{expected one of [bss|data|rodata|text] section kind in '#pragma clang section'}}
+
+#pragma clang section bss "mybss.2"   // expected-error {{expected '=' following '#pragma clang section bss'}}
+#pragma clang section data "mydata.2"   // expected-error {{expected '=' following '#pragma clang section data'}}
+#pragma clang section rodata "myrodata.2"   // expected-error {{expected '=' following '#pragma clang section rodata'}}
+#pragma clang section bss="" data="" rodata="" text="" more //expected-error {{expected one of [bss|data|rodata|text] section kind in '#pragma clang section'}}
+int a;
Index: test/CodeGenCXX/clang-sections.cpp
===
--- /dev/null
+++ test/CodeGenCXX/clang-sections.cpp
@@ -0,0 +1,78 @@
+// RUN: %clang_cc1 -emit-llvm -triple arm-none-eabi -o - %s | FileCheck %s
+// Test that global variables, statics and functions are attached section-attributes
+// as per '#pragma clang section' directives.
+
+extern "C" {
+// test with names for each section
+#pragma clang section bss="my_bss.1" data="my_data.1" rodata="my_rodata.1"
+#pragma clang section text="my_text.1"
+int a;  // my_bss.1
+int b = 1;  // my_data.1
+int c[4];   // my_bss.1
+short d[5] = {0}; // my_bss.1
+short e[6] = {0, 0, 1}; // my_data.1
+extern const int f;
+const int f = 2;  // my_rodata.1
+int foo(void) {   // my_text.1
+  return b;
+}
+static int g[2]; // my_bss.1
+#pragma clang section bss=""
+int h; // default - .bss
+#pragma clang section data=""  bss="my_bss.2" text="my_text.2"
+int i = 0; // my_bss.2
+extern const int j;
+const int j = 4; // default - .rodata
+int k; // my_bss.2
+extern int zoo(int *x, int *y);
+int goo(void) {  // my_text.2
+  static int lstat_h;  // my_bss.2
+  return zoo(g, _h);
+}
+#pragma clang section rodata="my_rodata.2" data="my_data.2"
+int l = 5; // my_data.2
+extern const int m;
+const int m = 6; // my_rodata.2
+#pragma clang section rodata="" data="" bss="" text=""
+int n; // default
+int o = 6; // default
+extern const int p;
+const int p = 7; // default
+int hoo(void) {
+  return b;
+}
+}
+//CHECK: @a = global i32 0, align 4 #0
+//CHECK: @b = global i32 1, align 4 #0
+//CHECK: @c = global [4 x i32] zeroinitializer, align 4 #0
+//CHECK: @d = global [5 x i16] zeroinitializer, align 2 #0
+//CHECK: @e = global [6 x i16] [i16 0, i16 0, i16 1, i16 0, i16 0, i16 0], align 2 #0
+//CHECK: @f = constant i32 2, align 4 #0
+
+//CHECK: @h = global i32 0, align 4 #1
+//CHECK: @i = global i32 0, align 4 #2
+//CHECK: @j = constant i32 4, align 4 #2
+//CHECK: @k = global i32 0, align 4 #2
+//CHECK: @_ZZ3gooE7lstat_h = internal global i32 0, align 4 #2
+//CHECK: @_ZL1g = internal global [2 x i32] zeroinitializer, align 4 #0
+
+//CHECK: @l = global i32 5, align 4 #3
+//CHECK: @m = constant i32 6, align 4 #3
+
+//CHECK: @n = global i32 0, align 4
+//CHECK: @o = global i32 6, align 4
+//CHECK: @p = constant i32 7, align 4
+
+//CHECK: define i32 @foo() #4 {
+//CHECK: define i32 @goo() #5 {
+//CHECK: declare i32 @zoo(i32*, i32*) #6
+//CHECK: define i32 @hoo() #7 {
+
+//CHECK: attributes #0 = { "bss-section"="my_bss.1" "data-section"="my_data.1" "rodata-section"="my_rodata.1" }
+//CHECK: attributes #1 = { "data-section"="my_data.1" 

[PATCH] D33412: Add support for #pragma clang section

2017-05-22 Thread Javed Absar via Phabricator via cfe-commits
javed.absar created this revision.
Herald added a subscriber: aemerson.

This patch adds support for a '#pragma clang section' directive in clang.
 An RFC was sent out earlier by my colleague  James Molloy:
 http://lists.llvm.org/pipermail/cfe-dev/2017-March/053100.html

  

Purpose:

  The purpose of this is to provide to developers a means to specify 
section-names
  for global variables, functions and static variables, using #pragma 
directives.
  This will provide a migration path towards clang for developers in the 
embedded
  and automotive domain. For example, AUTOSAR, an automotive standard, mandates
  the use of a #pragma in header files to determine in which sections 
initialized
  and uninitialized data get put into.
  This feature is implemented in our legacy ARM Compiler 5 toolchain and GCC 
forks
  used across the automotive space that have this feature implemented compatible
  with the ARM Compiler 5 implementation. The documentation is here:
  
http://infocenter.arm.com/help/index.jsp?topic=/com.arm.doc.dui0472m/chr1359124985290.html


User-Visible Behavior:

  The developer can specify section names as:
#pragma clang section bss="myBSS" data="myData" rodata="myRodata" 
text="myText"
  
  The developer can "unspecify" a section name with empty string e.g.
#pragma clang section bss="" data="" text="" rodata=""
  
  1. The pragma applies to all global variable, statics and function 
declarations
  from the pragma to the end of the translation unit.
  2. The pragma clang section is enabled automatically, without need of any 
flags.
  3. This feature is only defined to work sensibly for ELF targets.
  4. If section name is specified through _attribute_((section("myname"))), then
  the attribute name gains precedence over any applicable section name via 
pragma directives.
  5. Global variables, including - basic types, arrays, struct - that are 
initialized to zero
   e.g. int x = 0; will be placed in the named bss section, if one is present.  
  
  6. The section type using '#pragma clang section' approach does not does NOT
  try to infer section-kind from the name.
  For example, assigning a section ".bss.mysec" does NOT mean it will be placed 
in BSS.


Design:

  The decision about which section-kind applies to each global is not taken by 
this
  implementation but is purely inquired from the default back-end 
implementation in LLVM.
  Once the section-kind is known, appropriate section name as specified by the 
user
  using pragma directive, is applied to that global.
  Note that this is more effective approach than choosing the section name in 
the front-end
  when optimisation passes have not been run and the final proper section is 
not known.

There is a llvm corresponding patch with this patch.


https://reviews.llvm.org/D33412

Files:
  include/clang/Basic/Attr.td
  include/clang/Basic/DiagnosticParseKinds.td
  include/clang/Parse/Parser.h
  include/clang/Sema/Sema.h
  lib/CodeGen/CGDecl.cpp
  lib/CodeGen/CodeGenModule.cpp
  lib/Parse/ParsePragma.cpp
  lib/Sema/SemaAttr.cpp
  lib/Sema/SemaDecl.cpp
  test/CodeGenCXX/clang-sections-tentative.c
  test/CodeGenCXX/clang-sections.cpp
  test/Sema/pragma-clang-section.c

Index: test/Sema/pragma-clang-section.c
===
--- /dev/null
+++ test/Sema/pragma-clang-section.c
@@ -0,0 +1,17 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s -triple arm-none-eabi
+#pragma clang section bss="mybss.1" data="mydata.1" rodata="myrodata.1" text="mytext.1"
+#pragma clang section bss="" data="" rodata="" text=""
+#pragma clang section
+
+#pragma clang section dss="mybss.2" // expected-error {{expected one of [bss|data|rodata|text] section kind in '#pragma clang section'}}
+#pragma clang section deta="mydata.2" // expected-error {{expected one of [bss|data|rodata|text] section kind in '#pragma clang section'}}
+#pragma clang section rodeta="rodata.2" // expected-error {{expected one of [bss|data|rodata|text] section kind in '#pragma clang section'}}
+#pragma clang section taxt="text.2" // expected-error {{expected one of [bss|data|rodata|text] section kind in '#pragma clang section'}}
+
+#pragma clang section section bss="mybss.2"  // expected-error {{expected one of [bss|data|rodata|text] section kind in '#pragma clang section'}}
+
+#pragma clang section bss "mybss.2"   // expected-error {{expected '=' following '#pragma clang section bss'}}
+#pragma clang section data "mydata.2"   // expected-error {{expected '=' following '#pragma clang section data'}}
+#pragma clang section rodata "myrodata.2"   // expected-error {{expected '=' following '#pragma clang section rodata'}}
+#pragma clang section bss="" data="" rodata="" text="" more //expected-error {{expected one of [bss|data|rodata|text] section kind in '#pragma clang section'}}
+int a;
Index: test/CodeGenCXX/clang-sections.cpp
===
--- /dev/null
+++ 

[PATCH] D30326: [MS-ABI] Allow #pragma section to choose for ZI data

2017-03-01 Thread Javed Absar via Phabricator via cfe-commits
javed.absar added a comment.

Hi Nico:
This is for the case when using  '#pragma bss_seg..' feature outside of msvc 
context. That's the reason for the flag.
One could use attribute, but as attribute is attached to individual 
declaration, while pragma applies to whole file (unless superseded by another 
pragma),  the latter is easier to use in some cases (i.e. when there are lots 
of such declarations). Hope this clarifies the question you asked.
Best Regards
Javed


https://reviews.llvm.org/D30326



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D30326: [MS-ABI] Allow #pragma section to choose for ZI data

2017-02-27 Thread Javed Absar via Phabricator via cfe-commits
javed.absar updated this revision to Diff 89897.
javed.absar added a comment.

Hi Roger:
Thanks for the review. I have extended the test and fixed driver flag passing 
that you pointed out.

Regarding the check in Sema::DeclarationIsZeroInitialized, the check if to keep 
the function return value consistent, in case function is called with a 
declaration that is without an initializer.
Best Regards, 
Javed


https://reviews.llvm.org/D30326

Files:
  include/clang/AST/APValue.h
  include/clang/AST/Expr.h
  include/clang/Basic/LangOptions.def
  include/clang/Driver/Options.td
  include/clang/Sema/Sema.h
  lib/AST/APValue.cpp
  lib/AST/Expr.cpp
  lib/Driver/Tools.cpp
  lib/Frontend/CompilerInvocation.cpp
  lib/Sema/SemaDecl.cpp
  test/CodeGenCXX/zi-sections.cpp
  test/Driver/always-use-bss.c

Index: test/Driver/always-use-bss.c
===
--- /dev/null
+++ test/Driver/always-use-bss.c
@@ -0,0 +1,3 @@
+// RUN: %clang -### -target i686-pc-windows -fms-extensions -falways-use-bss %s 2>&1 | FileCheck %s
+// CHECK: "-falways-use-bss"
+void f() {}
Index: test/CodeGenCXX/zi-sections.cpp
===
--- /dev/null
+++ test/CodeGenCXX/zi-sections.cpp
@@ -0,0 +1,86 @@
+// RUN: %clang_cc1 -emit-llvm -triple i686-pc-win32 -fms-extensions -o - %s | FileCheck %s --check-prefix=CHECK --check-prefix=CHECK-ZI-DATA
+// RUN: %clang_cc1 -emit-llvm -triple i686-pc-win32 -fms-extensions -falways-use-bss -o - %s | FileCheck %s --check-prefix=CHECK --check-prefix=CHECK-ZI-BSS
+// Test that when '-falways-use-bss' is specified, variables initialized with zero are assigned to bss_seg.
+#pragma bss_seg(".bss.1")
+#pragma data_seg(".data.1")
+extern "C" {
+short ShortZero = 0;
+short ShortTwo = 2;
+short ShortMinusTwo = -2;
+short ShortUnInit;
+
+int IntZero = 0;
+int IntTwo = 2;
+int IntMinusTwo = -2;
+int IntUnInit;
+
+float FloatZero = 0.0;
+float FloatMinusZero = -0.0;
+float FloatTwo = 2.0;
+float FloatUnInit;
+
+double DoubleZero = 0.0;
+double DoubleMinusZero = -0.0;
+double DoubleTwo = 2.0;
+double DoubleUnInit;
+
+struct S {
+  int x, y;
+  int z;
+};
+struct S StructZero = { 0, 0, 0 };
+struct S StructTwo = { 0, 0, 2};
+struct S StructMinusTwo = {0, -2, 0};
+struct S StructUnInit;
+
+int ArrayZero[] = {0, 0, 0};
+int ArrayTwo[] = {0, 2, 0};
+int ArrayMinusTwo[] = {0, -2, 0};
+int ArrayUnInit;
+
+int ArrayWithFillerZero[10] = { 0 };
+int ArrayWithFillerTwo[10] = { 0, 2 };
+int ArrayWithAllFiller[10] = { };
+
+// CHECK-ZI-DATA: @ShortZero = global i16 0, section ".data.1", align 2
+// CHECK-ZI-BSS: @ShortZero = global i16 0, section ".bss.1", align 2
+// CHECK: @ShortTwo = global i16 2, section ".data.1", align 2
+// CHECK: @ShortMinusTwo = global i16 -2, section ".data.1", align 2
+// CHECK: @ShortUnInit = global i16 0, section ".bss.1", align 2
+//
+// CHECK-ZI-DATA: @IntZero = global i32 0, section ".data.1", align 4
+// CHECK-ZI-BSS: @IntZero = global i32 0, section ".bss.1", align 4
+// CHECK: @IntTwo = global i32 2, section ".data.1", align 4
+// CHECK: @IntMinusTwo = global i32 -2, section ".data.1", align 4
+// CHECK: @IntUnInit = global i32 0, section ".bss.1", align 4
+//
+// CHECK-ZI-DATA: @FloatZero = global float 0.00e+00, section ".data.1", align 4
+// CHECK-ZI-BSS: @FloatZero = global float 0.00e+00, section ".bss.1", align 4
+// CHECK: @FloatMinusZero = global float -0.00e+00, section ".data.1", align 4
+// CHECK: @FloatTwo = global float 2.00e+00, section ".data.1", align 4
+// CHECK: @FloatUnInit = global float 0.00e+00, section ".bss.1", align 4
+//
+// CHECK-ZI-DATA: @DoubleZero = global double 0.00e+00, section ".data.1", align 8
+// CHECK-ZI-BSS: @DoubleZero = global double 0.00e+00, section ".bss.1", align 8
+// CHECK: @DoubleMinusZero = global double -0.00e+00, section ".data.1", align 8
+// CHECK: @DoubleTwo = global double 2.00e+00, section ".data.1", align 8
+// CHECK: @DoubleUnInit = global double 0.00e+00, section ".bss.1", align 8
+//
+// CHECK-ZI-DATA: @StructZero = global %struct.S zeroinitializer, section ".data.1", align 4
+// CHECK-ZI-BSS: @StructZero = global %struct.S zeroinitializer, section ".bss.1", align 4
+// CHECK: @StructTwo = global %struct.S { i32 0, i32 0, i32 2 }, section ".data.1", align 4
+// CHECK: @StructMinusTwo = global %struct.S { i32 0, i32 -2, i32 0 }, section ".data.1", align 4
+// CHECK: @StructUnInit = global %struct.S zeroinitializer, section ".data.1", align 4
+//
+// CHECK-ZI-DATA: @ArrayZero = global [3 x i32] zeroinitializer, section ".data.1", align 4
+// CHECK-ZI-BSS: @ArrayZero = global [3 x i32] zeroinitializer, section ".bss.1", align 4
+// CHECK: @ArrayTwo = global [3 x i32] [i32 0, i32 2, i32 0], section ".data.1", align 4
+// CHECK: @ArrayMinusTwo = global [3 x i32] [i32 0, i32 -2, i32 0], section ".data.1", align 4
+// CHECK: @ArrayUnInit = global i32 0, section ".bss.1", align 4
+//
+// CHECK-ZI-DATA: 

[PATCH] D30326: [MS-ABI] Allow #pragma section to choose for ZI data

2017-02-24 Thread Javed Absar via Phabricator via cfe-commits
javed.absar created this revision.

This patch enables the msvc pragma section to choose whether zero initialized 
variables are to be placed in data_seg or bss_seg. The current 
implementation  ignores bss_seg directive for variables that are initialized 
(i.e. it does not check if the initialization is, in fact, to all zeros). 
This patch now allows that. The variables are now placed in named bss_seg but 
only so If (a) the initialization is all zeros; AND (b) ''-falways-use-bss flag 
is set'. In other words, current functionality is not impacted and a useful 
feature is provided to users.


https://reviews.llvm.org/D30326

Files:
  include/clang/AST/APValue.h
  include/clang/AST/Expr.h
  include/clang/Basic/LangOptions.def
  include/clang/Driver/Options.td
  include/clang/Sema/Sema.h
  lib/AST/APValue.cpp
  lib/AST/Expr.cpp
  lib/Driver/Tools.cpp
  lib/Frontend/CompilerInvocation.cpp
  lib/Sema/SemaDecl.cpp
  test/CodeGenCXX/zi-sections.cpp

Index: test/CodeGenCXX/zi-sections.cpp
===
--- /dev/null
+++ test/CodeGenCXX/zi-sections.cpp
@@ -0,0 +1,75 @@
+// RUN: %clang_cc1 -emit-llvm -triple i686-pc-win32 -fms-extensions -o - %s | FileCheck %s --check-prefix=CHECK --check-prefix=CHECK-ZI-DATA
+// RUN: %clang_cc1 -emit-llvm -triple i686-pc-win32 -fms-extensions -falways-use-bss -o - %s | FileCheck %s --check-prefix=CHECK --check-prefix=CHECK-ZI-BSS
+// Test that when '-falways-use-bss' is specified, variables initialized with zero are assigned to bss_seg.
+#pragma bss_seg(".bss.1")
+#pragma data_seg(".data.1")
+extern "C" {
+short ShortZero = 0;
+short ShortTwo = 2;
+short ShortMinusTwo = -2;
+short ShortUnInit;
+
+int IntZero = 0;
+int IntTwo = 2;
+int IntMinusTwo = -2;
+int IntUnInit;
+
+float FloatZero = 0.0;
+float FloatMinusZero = -0.0;
+float FloatTwo = 2.0;
+float FloatUnInit;
+
+double DoubleZero = 0.0;
+double DoubleMinusZero = -0.0;
+double DoubleTwo = 2.0;
+double DoubleUnInit;
+
+struct S {
+  int x, y;
+  int z;
+};
+struct S StructZero = { 0, 0, 0 };
+struct S StructTwo = { 0, 0, 2};
+struct S StructMinusTwo = {0, -2, 0};
+struct S StructUnInit;
+
+int ArrayZero[] = {0, 0, 0};
+int ArrayTwo[] = {0, 2, 0};
+int ArrayMinusTwo[] = {0, -2, 0};
+int ArrayUnInit;
+// CHECK-ZI-DATA: @ShortZero = global i16 0, section ".data.1", align 2
+// CHECK-ZI-BSS: @ShortZero = global i16 0, section ".bss.1", align 2
+// CHECK: @ShortTwo = global i16 2, section ".data.1", align 2
+// CHECK: @ShortMinusTwo = global i16 -2, section ".data.1", align 2
+// CHECK: @ShortUnInit = global i16 0, section ".bss.1", align 2
+//
+// CHECK-ZI-DATA: @IntZero = global i32 0, section ".data.1", align 4
+// CHECK-ZI-BSS: @IntZero = global i32 0, section ".bss.1", align 4
+// CHECK: @IntTwo = global i32 2, section ".data.1", align 4
+// CHECK: @IntMinusTwo = global i32 -2, section ".data.1", align 4
+// CHECK: @IntUnInit = global i32 0, section ".bss.1", align 4
+//
+// CHECK-ZI-DATA: @FloatZero = global float 0.00e+00, section ".data.1", align 4
+// CHECK-ZI-BSS: @FloatZero = global float 0.00e+00, section ".bss.1", align 4
+// CHECK: @FloatMinusZero = global float -0.00e+00, section ".data.1", align 4
+// CHECK: @FloatTwo = global float 2.00e+00, section ".data.1", align 4
+// CHECK: @FloatUnInit = global float 0.00e+00, section ".bss.1", align 4
+//
+// CHECK-ZI-DATA: @DoubleZero = global double 0.00e+00, section ".data.1", align 8
+// CHECK-ZI-BSS: @DoubleZero = global double 0.00e+00, section ".bss.1", align 8
+// CHECK: @DoubleMinusZero = global double -0.00e+00, section ".data.1", align 8
+// CHECK: @DoubleTwo = global double 2.00e+00, section ".data.1", align 8
+// CHECK: @DoubleUnInit = global double 0.00e+00, section ".bss.1", align 8
+//
+// CHECK-ZI-DATA: @StructZero = global %struct.S zeroinitializer, section ".data.1", align 4
+// CHECK-ZI-BSS: @StructZero = global %struct.S zeroinitializer, section ".bss.1", align 4
+// CHECK: @StructTwo = global %struct.S { i32 0, i32 0, i32 2 }, section ".data.1", align 4
+// CHECK: @StructMinusTwo = global %struct.S { i32 0, i32 -2, i32 0 }, section ".data.1", align 4
+// CHECK: @StructUnInit = global %struct.S zeroinitializer, section ".data.1", align 4
+//
+// CHECK-ZI-DATA: @ArrayZero = global [3 x i32] zeroinitializer, section ".data.1", align 4
+// CHECK-ZI-BSS: @ArrayZero = global [3 x i32] zeroinitializer, section ".bss.1", align 4
+// CHECK: @ArrayTwo = global [3 x i32] [i32 0, i32 2, i32 0], section ".data.1", align 4
+// CHECK: @ArrayMinusTwo = global [3 x i32] [i32 0, i32 -2, i32 0], section ".data.1", align 4
+// CHECK: @ArrayUnInit = global i32 0, section ".bss.1", align 4
+}
Index: lib/Sema/SemaDecl.cpp
===
--- lib/Sema/SemaDecl.cpp
+++ lib/Sema/SemaDecl.cpp
@@ -10736,6 +10736,18 @@
AttrEnd.isValid() ? AttrEnd : IdentLoc);
 }
 
+/// Check if initialization is to zero
+bool