[ARM] Check target feature support for __builtin_arm_crc*
authorFangrui Song <i@maskray.me>
Wed, 21 Sep 2022 18:50:15 +0000 (11:50 -0700)
committerFangrui Song <i@maskray.me>
Wed, 21 Sep 2022 18:50:15 +0000 (11:50 -0700)
`__builtin_arm_crc*` requires the target feature crc which is available on armv8
and above. Calling the fuctions for armv7 leads to a SelectionDAG crash.

```
% clang -c --target=armv7-unknown-linux-gnueabi -c a.c
fatal error: error in backend: Cannot select: intrinsic %llvm.arm.crc32b
PLEASE submit a bug report to ...
```

Add `TARGET_BUILTIN` and define required features for these builtins to
report an error in `CodeGenFunction::checkTargetFeatures`. The problem is quite widespread.
I will add `TARGET_BUILTIN` for more builtins later.

Fix https://github.com/llvm/llvm-project/issues/57802

Differential Revision: https://reviews.llvm.org/D134127

clang/include/clang/Basic/BuiltinsARM.def
clang/lib/Basic/Targets/ARM.cpp
clang/test/CodeGen/arm-crc32.c

index 0cea0a9..53fe64c 100644 (file)
 #   define LANGBUILTIN(ID, TYPE, ATTRS, BUILTIN_LANG) BUILTIN(ID, TYPE, ATTRS)
 #endif
 
+#if defined(BUILTIN) && !defined(TARGET_BUILTIN)
+#  define TARGET_BUILTIN(ID, TYPE, ATTRS, FEATURE) BUILTIN(ID, TYPE, ATTRS)
+#endif
+
 #if defined(BUILTIN) && !defined(TARGET_HEADER_BUILTIN)
 #  define TARGET_HEADER_BUILTIN(ID, TYPE, ATTRS, HEADER, LANG, FEATURE) BUILTIN(ID, TYPE, ATTRS)
 #endif
@@ -157,14 +161,14 @@ BUILTIN(__builtin_arm_mrrc, "LLUiUIiUIiUIi", "")
 BUILTIN(__builtin_arm_mrrc2, "LLUiUIiUIiUIi", "")
 
 // CRC32
-BUILTIN(__builtin_arm_crc32b, "UiUiUc", "nc")
-BUILTIN(__builtin_arm_crc32cb, "UiUiUc", "nc")
-BUILTIN(__builtin_arm_crc32h, "UiUiUs", "nc")
-BUILTIN(__builtin_arm_crc32ch, "UiUiUs", "nc")
-BUILTIN(__builtin_arm_crc32w, "UiUiUi", "nc")
-BUILTIN(__builtin_arm_crc32cw, "UiUiUi", "nc")
-BUILTIN(__builtin_arm_crc32d, "UiUiLLUi", "nc")
-BUILTIN(__builtin_arm_crc32cd, "UiUiLLUi", "nc")
+TARGET_BUILTIN(__builtin_arm_crc32b, "UiUiUc", "nc", "crc")
+TARGET_BUILTIN(__builtin_arm_crc32cb, "UiUiUc", "nc", "crc")
+TARGET_BUILTIN(__builtin_arm_crc32h, "UiUiUs", "nc", "crc")
+TARGET_BUILTIN(__builtin_arm_crc32ch, "UiUiUs", "nc", "crc")
+TARGET_BUILTIN(__builtin_arm_crc32w, "UiUiUi", "nc", "crc")
+TARGET_BUILTIN(__builtin_arm_crc32cw, "UiUiUi", "nc", "crc")
+TARGET_BUILTIN(__builtin_arm_crc32d, "UiUiLLUi", "nc", "crc")
+TARGET_BUILTIN(__builtin_arm_crc32cd, "UiUiLLUi", "nc", "crc")
 
 // ARMv8-M Security Extensions a.k.a CMSE
 BUILTIN(__builtin_arm_cmse_TT, "Uiv*", "n")
index b2f61cf..159b00d 100644 (file)
@@ -979,6 +979,8 @@ const Builtin::Info ARMTargetInfo::BuiltinInfo[] = {
   {#ID, TYPE, ATTRS, nullptr, LANG, nullptr},
 #define LIBBUILTIN(ID, TYPE, ATTRS, HEADER)                                    \
   {#ID, TYPE, ATTRS, HEADER, ALL_LANGUAGES, nullptr},
+#define TARGET_BUILTIN(ID, TYPE, ATTRS, FEATURE)                               \
+  {#ID, TYPE, ATTRS, nullptr, ALL_LANGUAGES, FEATURE},
 #define TARGET_HEADER_BUILTIN(ID, TYPE, ATTRS, HEADER, LANGS, FEATURE)         \
   {#ID, TYPE, ATTRS, HEADER, LANGS, FEATURE},
 #include "clang/Basic/BuiltinsARM.def"
index c9aa549..d6e3b1b 100644 (file)
@@ -1,8 +1,10 @@
-// RUN: %clang_cc1 -triple armv8-none-linux-gnueabi \
+// RUN: %clang_cc1 -triple armv8-none-linux-gnueabi -target-feature +crc \
 // RUN:  -disable-O0-optnone -emit-llvm -o - %s | opt -S -mem2reg | FileCheck %s
+// RUN: %clang_cc1 -verify -emit-llvm -triple armv7-none-linux-gnueabi %s
 
 int crc32b(int a, char b)
 {
+// expected-error@+1 {{'__builtin_arm_crc32b' needs target feature crc}}
         return __builtin_arm_crc32b(a,b);
 // CHECK: [[T0:%[0-9]+]] = zext i8 %b to i32
 // CHECK: call i32 @llvm.arm.crc32b(i32 %a, i32 [[T0]])