Fix TBAA for unsigned fixed-point types
authorMikael Holmen <mikael.holmen@ericsson.com>
Fri, 27 Mar 2020 09:12:11 +0000 (10:12 +0100)
committerMikael Holmen <mikael.holmen@ericsson.com>
Fri, 27 Mar 2020 09:35:24 +0000 (10:35 +0100)
Summary:
Unsigned types can alias the corresponding signed types. I don't see
that this is explicitly mentioned in the Embedded-C specification, but
I think it should work the same as for the integer types.

Patch by: materi

Reviewers: ebevhan, leonardchan

Reviewed By: leonardchan

Subscribers: kosarev, cfe-commits

Tags: #clang

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

clang/lib/CodeGen/CodeGenTBAA.cpp
clang/test/CodeGen/fixed-point-tbaa.c [new file with mode: 0644]

index 7d730cb..8cc8c16 100644 (file)
@@ -141,6 +141,34 @@ llvm::MDNode *CodeGenTBAA::getTypeInfoHelper(const Type *Ty) {
     case BuiltinType::UInt128:
       return getTypeInfo(Context.Int128Ty);
 
+    case BuiltinType::UShortFract:
+      return getTypeInfo(Context.ShortFractTy);
+    case BuiltinType::UFract:
+      return getTypeInfo(Context.FractTy);
+    case BuiltinType::ULongFract:
+      return getTypeInfo(Context.LongFractTy);
+
+    case BuiltinType::SatUShortFract:
+      return getTypeInfo(Context.SatShortFractTy);
+    case BuiltinType::SatUFract:
+      return getTypeInfo(Context.SatFractTy);
+    case BuiltinType::SatULongFract:
+      return getTypeInfo(Context.SatLongFractTy);
+
+    case BuiltinType::UShortAccum:
+      return getTypeInfo(Context.ShortAccumTy);
+    case BuiltinType::UAccum:
+      return getTypeInfo(Context.AccumTy);
+    case BuiltinType::ULongAccum:
+      return getTypeInfo(Context.LongAccumTy);
+
+    case BuiltinType::SatUShortAccum:
+      return getTypeInfo(Context.SatShortAccumTy);
+    case BuiltinType::SatUAccum:
+      return getTypeInfo(Context.SatAccumTy);
+    case BuiltinType::SatULongAccum:
+      return getTypeInfo(Context.SatLongAccumTy);
+
     // Treat all other builtin types as distinct types. This includes
     // treating wchar_t, char16_t, and char32_t as distinct from their
     // "underlying types".
diff --git a/clang/test/CodeGen/fixed-point-tbaa.c b/clang/test/CodeGen/fixed-point-tbaa.c
new file mode 100644 (file)
index 0000000..0698603
--- /dev/null
@@ -0,0 +1,109 @@
+// RUN: %clang_cc1 -triple x86_64-apple-darwin -O1 -ffixed-point %s -emit-llvm -o - | FileCheck %s  -check-prefixes=CHECK
+//
+// Check that we generate correct TBAA metadata for fixed-point types.
+
+void sfract(unsigned short _Fract *p, short _Fract *q,
+            unsigned _Sat short _Fract *r, _Sat short _Fract *s) {
+  // CHECK-LABEL: define void @sfract
+  // CHECK: store i8 -128, i8* %p, align 1, !tbaa [[TAG_sf:!.*]]
+  // CHECK: store i8 -64, i8* %q, align 1, !tbaa [[TAG_sf]]
+  // CHECK: store i8 -128, i8* %r, align 1, !tbaa [[TAG_sat_sf:!.*]]
+  // CHECK: store i8 -64, i8* %s, align 1, !tbaa [[TAG_sat_sf]]
+  *p = 0.5hur;
+  *q = -0.5hr;
+  *r = 0.5hur;
+  *s = -0.5hr;
+}
+
+void fract(unsigned _Fract *p, _Fract *q,
+           unsigned _Sat _Fract *r, _Sat _Fract *s) {
+  // CHECK-LABEL: define void @fract
+  // CHECK: store i16 -32768, i16* %p, align 2, !tbaa [[TAG_f:!.*]]
+  // CHECK: store i16 -16384, i16* %q, align 2, !tbaa [[TAG_f]]
+  // CHECK: store i16 -32768, i16* %r, align 2, !tbaa [[TAG_sat_f:!.*]]
+  // CHECK: store i16 -16384, i16* %s, align 2, !tbaa [[TAG_sat_f]]
+  *p = 0.5ur;
+  *q = -0.5r;
+  *r = 0.5ur;
+  *s = -0.5r;
+}
+
+void lfract(unsigned long _Fract *p, long _Fract *q,
+            unsigned _Sat long _Fract *r, _Sat long _Fract *s) {
+  // CHECK-LABEL: define void @lfract
+  // CHECK: store i32 -2147483648, i32* %p, align 4, !tbaa [[TAG_lf:!.*]]
+  // CHECK: store i32 -1073741824, i32* %q, align 4, !tbaa [[TAG_lf]]
+  // CHECK: store i32 -2147483648, i32* %r, align 4, !tbaa [[TAG_sat_lf:!.*]]
+  // CHECK: store i32 -1073741824, i32* %s, align 4, !tbaa [[TAG_sat_lf]]
+  *p = 0.5ulr;
+  *q = -0.5lr;
+  *r = 0.5ulr;
+  *s = -0.5lr;
+}
+
+void saccum(unsigned short _Accum *p, short _Accum *q,
+            unsigned _Sat short _Accum *r, _Sat short _Accum *s) {
+  // CHECK-LABEL: define void @saccum
+  // CHECK: store i16 128, i16* %p, align 2, !tbaa [[TAG_sk:!.*]]
+  // CHECK: store i16 -64, i16* %q, align 2, !tbaa [[TAG_sk]]
+  // CHECK: store i16 128, i16* %r, align 2, !tbaa [[TAG_sat_sk:!.*]]
+  // CHECK: store i16 -64, i16* %s, align 2, !tbaa [[TAG_sat_sk]]
+  *p = 0.5huk;
+  *q = -0.5hk;
+  *r = 0.5huk;
+  *s = -0.5hk;
+}
+
+void accum(unsigned _Accum *p, _Accum *q,
+           unsigned _Sat _Accum *r, _Sat _Accum *s) {
+  // CHECK-LABEL: define void @accum
+  // CHECK: store i32 32768, i32* %p, align 4, !tbaa [[TAG_k:!.*]]
+  // CHECK: store i32 -16384, i32* %q, align 4, !tbaa [[TAG_k]]
+  // CHECK: store i32 32768, i32* %r, align 4, !tbaa [[TAG_sat_k:!.*]]
+  // CHECK: store i32 -16384, i32* %s, align 4, !tbaa [[TAG_sat_k]]
+  *p = 0.5uk;
+  *q = -0.5k;
+  *r = 0.5uk;
+  *s = -0.5k;
+}
+
+void laccum(unsigned long _Accum *p, long _Accum *q,
+            unsigned _Sat long _Accum *r, _Sat long _Accum *s) {
+  // CHECK-LABEL: define void @laccum
+  // CHECK: store i64 2147483648, i64* %p, align 8, !tbaa [[TAG_lk:!.*]]
+  // CHECK: store i64 -1073741824, i64* %q, align 8, !tbaa [[TAG_lk]]
+  // CHECK: store i64 2147483648, i64* %r, align 8, !tbaa [[TAG_sat_lk:!.*]]
+  // CHECK: store i64 -1073741824, i64* %s, align 8, !tbaa [[TAG_sat_lk]]
+  *p = 0.5ulk;
+  *q = -0.5lk;
+  *r = 0.5ulk;
+  *s = -0.5lk;
+}
+
+// CHECK-DAG: [[TAG_sf]] = !{[[TYPE_sf:!.*]], [[TYPE_sf]], i64 0}
+// CHECK-DAG: [[TYPE_sf]] = !{!"short _Fract"
+// CHECK-DAG: [[TAG_f]] = !{[[TYPE_f:!.*]], [[TYPE_f]], i64 0}
+// CHECK-DAG: [[TYPE_f]] = !{!"_Fract"
+// CHECK-DAG: [[TAG_lf]] = !{[[TYPE_lf:!.*]], [[TYPE_lf]], i64 0}
+// CHECK-DAG: [[TYPE_lf]] = !{!"long _Fract"
+
+// CHECK-DAG: [[TAG_sat_sf]] = !{[[TYPE_sat_sf:!.*]], [[TYPE_sat_sf]], i64 0}
+// CHECK-DAG: [[TYPE_sat_sf]] = !{!"_Sat short _Fract"
+// CHECK-DAG: [[TAG_sat_f]] = !{[[TYPE_sat_f:!.*]], [[TYPE_sat_f]], i64 0}
+// CHECK-DAG: [[TYPE_sat_f]] = !{!"_Sat _Fract"
+// CHECK-DAG: [[TAG_sat_lf]] = !{[[TYPE_sat_lf:!.*]], [[TYPE_sat_lf]], i64 0}
+// CHECK-DAG: [[TYPE_sat_lf]] = !{!"_Sat long _Fract"
+
+// CHECK-DAG: [[TAG_sk]] = !{[[TYPE_sk:!.*]], [[TYPE_sk]], i64 0}
+// CHECK-DAG: [[TYPE_sk]] = !{!"short _Accum"
+// CHECK-DAG: [[TAG_k]] = !{[[TYPE_k:!.*]], [[TYPE_k]], i64 0}
+// CHECK-DAG: [[TYPE_k]] = !{!"_Accum"
+// CHECK-DAG: [[TAG_lk]] = !{[[TYPE_lk:!.*]], [[TYPE_lk]], i64 0}
+// CHECK-DAG: [[TYPE_lk]] = !{!"long _Accum"
+
+// CHECK-DAG: [[TAG_sat_sk]] = !{[[TYPE_sat_sk:!.*]], [[TYPE_sat_sk]], i64 0}
+// CHECK-DAG: [[TYPE_sat_sk]] = !{!"_Sat short _Accum"
+// CHECK-DAG: [[TAG_sat_k]] = !{[[TYPE_sat_k:!.*]], [[TYPE_sat_k]], i64 0}
+// CHECK-DAG: [[TYPE_sat_k]] = !{!"_Sat _Accum"
+// CHECK-DAG: [[TAG_sat_lk]] = !{[[TYPE_sat_lk:!.*]], [[TYPE_sat_lk]], i64 0}
+// CHECK-DAG: [[TYPE_sat_lk]] = !{!"_Sat long _Accum"