Ka-Ka updated this revision to Diff 199385.
Ka-Ka marked an inline comment as done.
Ka-Ka added a comment.

Added a new C++ testcase.
Removed the REQUIRES: avr-registered-target in the avr-builtins.c testcase.


Repository:
  rC Clang

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

https://reviews.llvm.org/D61845

Files:
  include/clang/Basic/Builtins.def
  lib/AST/ASTContext.cpp
  test/CodeGen/avr-builtins.c
  test/CodeGen/builtins.cpp

Index: test/CodeGen/builtins.cpp
===================================================================
--- /dev/null
+++ test/CodeGen/builtins.cpp
@@ -0,0 +1,55 @@
+// RUN: %clang_cc1 -std=c++11 -triple x86_64-linux-gnu -verify %s
+// RUN: %clang_cc1 -std=c++11 -triple i686-pc-linux-gnu -verify %s
+// RUN: %clang_cc1 -std=c++11 -triple avr-unknown-unknown -verify %s
+// RUN: %clang_cc1 -std=c++11 -triple powerpc-pc-linux -verify %s
+// RUN: %clang_cc1 -std=c++11 -triple arm-linux-gnueabi -verify %s
+
+// Test that checks that the builtins return the same type as the stdint.h type
+// withe the same witdh. This is done by first declaring a variable of a stdint
+// type of the correct width and the redeclaring the variable with the type that
+// the builting return. If the types are different you should the an error from
+// clang of the form:
+// "redefinition of '<varname>' with a different type: '<type1>' vs '<type2>'
+// (with gcc you get an error message
+// "conflicting declaration '<type> <varname>'").
+// If the types are the same you only get an error message of the form
+// "redefinition of '<varname>'"
+// with both clang and gcc.
+
+#include <stdint.h>
+
+uint16_t bswap16; // expected-note{{previous definition is here}}
+decltype(__builtin_bswap16(0)) bswap16 = 42; // expected-error-re{{redefinition of 'bswap16'{{$}}}}
+uint32_t bswap32; // expected-note{{previous definition is here}}
+decltype(__builtin_bswap32(0)) bswap32 = 42; // expected-error-re{{redefinition of 'bswap32'{{$}}}}
+uint64_t bswap64; // expected-note{{previous definition is here}}
+decltype(__builtin_bswap64(0)) bswap64 = 42; // expected-error-re{{redefinition of 'bswap64'{{$}}}}
+
+#ifdef __clang__
+uint8_t bitrev8; // expected-note{{previous definition is here}}
+decltype(__builtin_bitreverse8(0)) bitrev8 = 42; // expected-error-re{{redefinition of 'bitrev8'{{$}}}}
+uint16_t bitrev16; // expected-note{{previous definition is here}}
+decltype(__builtin_bitreverse16(0)) bitrev16 = 42; // expected-error-re{{redefinition of 'bitrev16'{{$}}}}
+uint32_t bitrev32; // expected-note{{previous definition is here}}
+decltype(__builtin_bitreverse32(0)) bitrev32 = 42; // expected-error-re{{redefinition of 'bitrev32'{{$}}}}
+uint64_t bitrev64; // expected-note{{previous definition is here}}
+decltype(__builtin_bitreverse64(0)) bitrev64 = 42; // expected-error-re{{redefinition of 'bitrev64'{{$}}}}
+
+uint8_t rotl8; // expected-note{{previous definition is here}}
+decltype(__builtin_rotateleft8(0,0)) rotl8 = 42; // expected-error-re{{redefinition of 'rotl8'{{$}}}}
+uint16_t rotl16; // expected-note{{previous definition is here}}
+decltype(__builtin_rotateleft16(0,0)) rotl16 = 42; // expected-error-re{{redefinition of 'rotl16'{{$}}}}
+uint32_t rotl32; // expected-note{{previous definition is here}}
+decltype(__builtin_rotateleft32(0,0)) rotl32 = 42; // expected-error-re{{redefinition of 'rotl32'{{$}}}}
+uint64_t rotl64; // expected-note{{previous definition is here}}
+decltype(__builtin_rotateleft64(0,0)) rotl64 = 42; // expected-error-re{{redefinition of 'rotl64'{{$}}}}
+
+uint8_t rotr8; // expected-note{{previous definition is here}}
+decltype(__builtin_rotateright8(0,0)) rotr8 = 42; // expected-error-re{{redefinition of 'rotr8'{{$}}}}
+uint16_t rotr16; // expected-note{{previous definition is here}}
+decltype(__builtin_rotateright16(0,0)) rotr16 = 42; // expected-error-re{{redefinition of 'rotr16'{{$}}}}
+uint32_t rotr32; // expected-note{{previous definition is here}}
+decltype(__builtin_rotateright32(0,0)) rotr32 = 42; // expected-error-re{{redefinition of 'rotr32'{{$}}}}
+uint64_t rotr64; // expected-note{{previous definition is here}}
+decltype(__builtin_rotateright64(0,0)) rotr64 = 42; // expected-error-re{{redefinition of 'rotr64'{{$}}}}
+#endif
Index: test/CodeGen/avr-builtins.c
===================================================================
--- /dev/null
+++ test/CodeGen/avr-builtins.c
@@ -0,0 +1,102 @@
+// RUN: %clang_cc1 -triple avr-unknown-unknown -emit-llvm -o - %s | FileCheck %s
+
+unsigned char bitrev8(unsigned char data) {
+    return __builtin_bitreverse8(data);
+}
+
+// CHECK: define zeroext i8 @bitrev8
+// CHECK: i8 @llvm.bitreverse.i8(i8
+
+unsigned int bitrev16(unsigned int data) {
+    return __builtin_bitreverse16(data);
+}
+
+// CHECK: define i16 @bitrev16
+// CHECK: i16 @llvm.bitreverse.i16(i16
+
+unsigned long bitrev32(unsigned long data) {
+    return __builtin_bitreverse32(data);
+}
+// CHECK: define i32 @bitrev32
+// CHECK: i32 @llvm.bitreverse.i32(i32
+
+unsigned long long bitrev64(unsigned long long data) {
+    return __builtin_bitreverse64(data);
+}
+
+// CHECK: define i64 @bitrev64
+// CHECK: i64 @llvm.bitreverse.i64(i64
+
+unsigned char rotleft8(unsigned char x, unsigned char y) {
+    return __builtin_rotateleft8(x, y);
+}
+
+// CHECK: define zeroext i8 @rotleft8
+// CHECK: i8 @llvm.fshl.i8(i8
+
+unsigned int rotleft16(unsigned int x, unsigned int y) {
+    return __builtin_rotateleft16(x, y);
+}
+
+// CHECK: define i16 @rotleft16
+// CHECK: i16 @llvm.fshl.i16(i16
+
+unsigned long rotleft32(unsigned long x, unsigned long y) {
+    return __builtin_rotateleft32(x, y);
+}
+// CHECK: define i32 @rotleft32
+// CHECK: i32 @llvm.fshl.i32(i32
+
+unsigned long long rotleft64(unsigned long long x, unsigned long long y) {
+    return __builtin_rotateleft64(x, y);
+}
+
+// CHECK: define i64 @rotleft64
+// CHECK: i64 @llvm.fshl.i64(i64
+
+unsigned char rotright8(unsigned char x, unsigned char y) {
+    return __builtin_rotateright8(x, y);
+}
+
+// CHECK: define zeroext i8 @rotright8
+// CHECK: i8 @llvm.fshr.i8(i8
+
+unsigned int rotright16(unsigned int x, unsigned int y) {
+    return __builtin_rotateright16(x, y);
+}
+
+// CHECK: define i16 @rotright16
+// CHECK: i16 @llvm.fshr.i16(i16
+
+unsigned long rotright32(unsigned long x, unsigned long y) {
+    return __builtin_rotateright32(x, y);
+}
+// CHECK: define i32 @rotright32
+// CHECK: i32 @llvm.fshr.i32(i32
+
+unsigned long long rotright64(unsigned long long x, unsigned long long y) {
+    return __builtin_rotateright64(x, y);
+}
+
+// CHECK: define i64 @rotright64
+// CHECK: i64 @llvm.fshr.i64(i64
+
+unsigned int byteswap16(unsigned int x) {
+    return __builtin_bswap16(x);
+}
+
+// CHECK: define i16 @byteswap16
+// CHECK: i16 @llvm.bswap.i16(i16
+
+unsigned long byteswap32(unsigned long x) {
+    return __builtin_bswap32(x);
+}
+// CHECK: define i32 @byteswap32
+// CHECK: i32 @llvm.bswap.i32(i32
+
+unsigned long long byteswap64(unsigned long long x) {
+    return __builtin_bswap64(x);
+}
+
+// CHECK: define i64 @byteswap64
+// CHECK: i64 @llvm.bswap.i64(i64
Index: lib/AST/ASTContext.cpp
===================================================================
--- lib/AST/ASTContext.cpp
+++ lib/AST/ASTContext.cpp
@@ -9312,7 +9312,7 @@
   // Read the prefixed modifiers first.
   bool Done = false;
   #ifndef NDEBUG
-  bool IsSpecialLong = false;
+  bool IsSpecial = false;
   #endif
   while (!Done) {
     switch (*Str++) {
@@ -9331,26 +9331,26 @@
       Unsigned = true;
       break;
     case 'L':
-      assert(!IsSpecialLong && "Can't use 'L' with 'W' or 'N' modifiers");
+      assert(!IsSpecial && "Can't use 'L' with 'W', 'N' or 'Z' modifiers");
       assert(HowLong <= 2 && "Can't have LLLL modifier");
       ++HowLong;
       break;
     case 'N':
       // 'N' behaves like 'L' for all non LP64 targets and 'int' otherwise.
-      assert(!IsSpecialLong && "Can't use two 'N' or 'W' modifiers!");
+      assert(!IsSpecial && "Can't use two 'N', 'W' or 'Z' modifiers!");
       assert(HowLong == 0 && "Can't use both 'L' and 'N' modifiers!");
       #ifndef NDEBUG
-      IsSpecialLong = true;
+      IsSpecial = true;
       #endif
       if (Context.getTargetInfo().getLongWidth() == 32)
         ++HowLong;
       break;
     case 'W':
       // This modifier represents int64 type.
-      assert(!IsSpecialLong && "Can't use two 'N' or 'W' modifiers!");
+      assert(!IsSpecial && "Can't use two 'N', 'W' or 'Z'  modifiers!");
       assert(HowLong == 0 && "Can't use both 'L' and 'W' modifiers!");
       #ifndef NDEBUG
-      IsSpecialLong = true;
+      IsSpecial = true;
       #endif
       switch (Context.getTargetInfo().getInt64Type()) {
       default:
@@ -9363,6 +9363,27 @@
         break;
       }
       break;
+    case 'Z':
+      // This modifier represents int32 type.
+      assert(!IsSpecial && "Can't use two 'N', 'W' or 'Z' modifiers!");
+      assert(HowLong == 0 && "Can't use both 'L' and 'Z' modifiers!");
+      #ifndef NDEBUG
+      IsSpecial = true;
+      #endif
+      switch (Context.getTargetInfo().getIntTypeByWidth(32, true)) {
+      default:
+        llvm_unreachable("Unexpected integer type");
+      case TargetInfo::SignedInt:
+        HowLong = 0;
+        break;
+      case TargetInfo::SignedLong:
+        HowLong = 1;
+        break;
+      case TargetInfo::SignedLongLong:
+        HowLong = 2;
+        break;
+      }
+      break;
     }
   }
 
Index: include/clang/Basic/Builtins.def
===================================================================
--- include/clang/Basic/Builtins.def
+++ include/clang/Basic/Builtins.def
@@ -50,7 +50,8 @@
 //  L   -> long (e.g. Li for 'long int', Ld for 'long double')
 //  LL  -> long long (e.g. LLi for 'long long int', LLd for __float128)
 //  LLL -> __int128_t (e.g. LLLi)
-//  W   -> int64_t
+//  Z   -> int32_t (require a native 32-bit integer type on the target)
+//  W   -> int64_t (require a native 64-bit integer type on the target)
 //  N   -> 'int' size if target is LP64, 'L' otherwise.
 //  S   -> signed
 //  U   -> unsigned
@@ -418,25 +419,27 @@
 BUILTIN(__builtin_clrsbl , "iLi" , "nc")
 BUILTIN(__builtin_clrsbll, "iLLi", "nc")
 
-// FIXME: These type signatures are not correct for targets with int != 32-bits
-// or with ULL != 64-bits.
+// The following builtins rely on that char == 8 bits, short == 16 bits and that
+// there exists native types on the target that are 32- and 64-bits wide, unless
+// these conditions are fulfilled these builtins will operate on a not intended
+// bitwidth.
 BUILTIN(__builtin_bswap16, "UsUs", "nc")
-BUILTIN(__builtin_bswap32, "UiUi", "nc")
-BUILTIN(__builtin_bswap64, "ULLiULLi", "nc")
+BUILTIN(__builtin_bswap32, "UZiUZi", "nc")
+BUILTIN(__builtin_bswap64, "UWiUWi", "nc")
 
 BUILTIN(__builtin_bitreverse8, "UcUc", "nc")
 BUILTIN(__builtin_bitreverse16, "UsUs", "nc")
-BUILTIN(__builtin_bitreverse32, "UiUi", "nc")
-BUILTIN(__builtin_bitreverse64, "ULLiULLi", "nc")
+BUILTIN(__builtin_bitreverse32, "UZiUZi", "nc")
+BUILTIN(__builtin_bitreverse64, "UWiUWi", "nc")
 
 BUILTIN(__builtin_rotateleft8, "UcUcUc", "nc")
 BUILTIN(__builtin_rotateleft16, "UsUsUs", "nc")
-BUILTIN(__builtin_rotateleft32, "UiUiUi", "nc")
-BUILTIN(__builtin_rotateleft64, "ULLiULLiULLi", "nc")
+BUILTIN(__builtin_rotateleft32, "UZiUZiUZi", "nc")
+BUILTIN(__builtin_rotateleft64, "UWiUWiUWi", "nc")
 BUILTIN(__builtin_rotateright8, "UcUcUc", "nc")
 BUILTIN(__builtin_rotateright16, "UsUsUs", "nc")
-BUILTIN(__builtin_rotateright32, "UiUiUi", "nc")
-BUILTIN(__builtin_rotateright64, "ULLiULLiULLi", "nc")
+BUILTIN(__builtin_rotateright32, "UZiUZiUZi", "nc")
+BUILTIN(__builtin_rotateright64, "UWiUWiWi", "nc")
 
 // Random GCC builtins
 BUILTIN(__builtin_constant_p, "i.", "nctu")
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to