| // NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py UTC_ARGS: --version 6 | |
| // RUN: %clang_cc1 -O1 -fenable-matrix -triple x86_64-linux \ | |
| // RUN: -emit-llvm -disable-llvm-passes -o - %s | FileCheck %s | |
| // | |
| // Check that we generate correct TBAA information for accesses to matrix types. | |
| typedef double dx5x5_t __attribute__((matrix_type(5, 5))); | |
| typedef float fx2x3_t __attribute__((matrix_type(2, 3))); | |
| typedef int ix3x3_t __attribute__((matrix_type(3, 3))); | |
| // CHECK-LABEL: define dso_local void @load_double_matrix( | |
| // CHECK-SAME: ptr noundef [[A:%.*]], ptr noundef [[B:%.*]]) #[[ATTR0:[0-9]+]] { | |
| // CHECK-NEXT: [[ENTRY:.*:]] | |
| // CHECK-NEXT: [[A_ADDR:%.*]] = alloca ptr, align 8 | |
| // CHECK-NEXT: [[B_ADDR:%.*]] = alloca ptr, align 8 | |
| // CHECK-NEXT: store ptr [[A]], ptr [[A_ADDR]], align 8, !tbaa [[ANYPTR_TBAA6:![0-9]+]] | |
| // CHECK-NEXT: store ptr [[B]], ptr [[B_ADDR]], align 8, !tbaa [[ANYPTR_TBAA6]] | |
| // CHECK-NEXT: [[TMP0:%.*]] = load ptr, ptr [[A_ADDR]], align 8, !tbaa [[ANYPTR_TBAA6]] | |
| // CHECK-NEXT: [[TMP1:%.*]] = load <25 x double>, ptr [[TMP0]], align 8, !tbaa [[DOUBLE_TBAA8:![0-9]+]] | |
| // CHECK-NEXT: [[TMP2:%.*]] = load ptr, ptr [[B_ADDR]], align 8, !tbaa [[ANYPTR_TBAA6]] | |
| // CHECK-NEXT: store <25 x double> [[TMP1]], ptr [[TMP2]], align 8, !tbaa [[DOUBLE_TBAA8]] | |
| // CHECK-NEXT: ret void | |
| // | |
| void load_double_matrix(dx5x5_t *a, dx5x5_t *b) { | |
| *b = *a; | |
| } | |
| // CHECK-LABEL: define dso_local void @load_float_matrix( | |
| // CHECK-SAME: ptr noundef [[A:%.*]], ptr noundef [[B:%.*]]) #[[ATTR0]] { | |
| // CHECK-NEXT: [[ENTRY:.*:]] | |
| // CHECK-NEXT: [[A_ADDR:%.*]] = alloca ptr, align 8 | |
| // CHECK-NEXT: [[B_ADDR:%.*]] = alloca ptr, align 8 | |
| // CHECK-NEXT: store ptr [[A]], ptr [[A_ADDR]], align 8, !tbaa [[ANYPTR_TBAA6]] | |
| // CHECK-NEXT: store ptr [[B]], ptr [[B_ADDR]], align 8, !tbaa [[ANYPTR_TBAA6]] | |
| // CHECK-NEXT: [[TMP0:%.*]] = load ptr, ptr [[A_ADDR]], align 8, !tbaa [[ANYPTR_TBAA6]] | |
| // CHECK-NEXT: [[TMP1:%.*]] = load <6 x float>, ptr [[TMP0]], align 4, !tbaa [[FLOAT_TBAA10:![0-9]+]] | |
| // CHECK-NEXT: [[TMP2:%.*]] = load ptr, ptr [[B_ADDR]], align 8, !tbaa [[ANYPTR_TBAA6]] | |
| // CHECK-NEXT: store <6 x float> [[TMP1]], ptr [[TMP2]], align 4, !tbaa [[FLOAT_TBAA10]] | |
| // CHECK-NEXT: ret void | |
| // | |
| void load_float_matrix(fx2x3_t *a, fx2x3_t *b) { | |
| *b = *a; | |
| } | |
| // CHECK-LABEL: define dso_local void @load_int_matrix( | |
| // CHECK-SAME: ptr noundef [[A:%.*]], ptr noundef [[B:%.*]]) #[[ATTR0]] { | |
| // CHECK-NEXT: [[ENTRY:.*:]] | |
| // CHECK-NEXT: [[A_ADDR:%.*]] = alloca ptr, align 8 | |
| // CHECK-NEXT: [[B_ADDR:%.*]] = alloca ptr, align 8 | |
| // CHECK-NEXT: store ptr [[A]], ptr [[A_ADDR]], align 8, !tbaa [[ANYPTR_TBAA6]] | |
| // CHECK-NEXT: store ptr [[B]], ptr [[B_ADDR]], align 8, !tbaa [[ANYPTR_TBAA6]] | |
| // CHECK-NEXT: [[TMP0:%.*]] = load ptr, ptr [[A_ADDR]], align 8, !tbaa [[ANYPTR_TBAA6]] | |
| // CHECK-NEXT: [[TMP1:%.*]] = load <9 x i32>, ptr [[TMP0]], align 4, !tbaa [[INT_TBAA12:![0-9]+]] | |
| // CHECK-NEXT: [[TMP2:%.*]] = load ptr, ptr [[B_ADDR]], align 8, !tbaa [[ANYPTR_TBAA6]] | |
| // CHECK-NEXT: store <9 x i32> [[TMP1]], ptr [[TMP2]], align 4, !tbaa [[INT_TBAA12]] | |
| // CHECK-NEXT: ret void | |
| // | |
| void load_int_matrix(ix3x3_t *a, ix3x3_t *b) { | |
| *b = *a; | |
| } | |
| // Verify that matrix and scalar accesses to the same element type share the | |
| // same TBAA tag. | |
| // CHECK-LABEL: define dso_local void @load_double_matrix_and_scalar( | |
| // CHECK-SAME: ptr noundef [[M:%.*]], ptr noundef [[S:%.*]]) #[[ATTR0]] { | |
| // CHECK-NEXT: [[ENTRY:.*:]] | |
| // CHECK-NEXT: [[M_ADDR:%.*]] = alloca ptr, align 8 | |
| // CHECK-NEXT: [[S_ADDR:%.*]] = alloca ptr, align 8 | |
| // CHECK-NEXT: [[LOCAL:%.*]] = alloca [25 x double], align 8 | |
| // CHECK-NEXT: [[D:%.*]] = alloca double, align 8 | |
| // CHECK-NEXT: store ptr [[M]], ptr [[M_ADDR]], align 8, !tbaa [[ANYPTR_TBAA6]] | |
| // CHECK-NEXT: store ptr [[S]], ptr [[S_ADDR]], align 8, !tbaa [[DOUBLEPTR_TBAA13:![0-9]+]] | |
| // CHECK-NEXT: call void @llvm.lifetime.start.p0(ptr [[LOCAL]]) #[[ATTR2:[0-9]+]] | |
| // CHECK-NEXT: [[TMP0:%.*]] = load ptr, ptr [[M_ADDR]], align 8, !tbaa [[ANYPTR_TBAA6]] | |
| // CHECK-NEXT: [[TMP1:%.*]] = load <25 x double>, ptr [[TMP0]], align 8, !tbaa [[DOUBLE_TBAA8]] | |
| // CHECK-NEXT: store <25 x double> [[TMP1]], ptr [[LOCAL]], align 8, !tbaa [[DOUBLE_TBAA8]] | |
| // CHECK-NEXT: call void @llvm.lifetime.start.p0(ptr [[D]]) #[[ATTR2]] | |
| // CHECK-NEXT: [[TMP2:%.*]] = load ptr, ptr [[S_ADDR]], align 8, !tbaa [[DOUBLEPTR_TBAA13]] | |
| // CHECK-NEXT: [[TMP3:%.*]] = load double, ptr [[TMP2]], align 8, !tbaa [[DOUBLE_TBAA8]] | |
| // CHECK-NEXT: store double [[TMP3]], ptr [[D]], align 8, !tbaa [[DOUBLE_TBAA8]] | |
| // CHECK-NEXT: call void @llvm.lifetime.end.p0(ptr [[D]]) #[[ATTR2]] | |
| // CHECK-NEXT: call void @llvm.lifetime.end.p0(ptr [[LOCAL]]) #[[ATTR2]] | |
| // CHECK-NEXT: ret void | |
| // | |
| void load_double_matrix_and_scalar(dx5x5_t *m, double *s) { | |
| dx5x5_t local = *m; | |
| double d = *s; | |
| } | |
| // Verify that may_alias on the element type is respected for matrix types. | |
| typedef int __attribute__((may_alias)) aliasing_int; | |
| typedef aliasing_int __attribute__((matrix_type(2, 2))) aim_t; | |
| // CHECK-LABEL: define dso_local void @load_may_alias_matrix( | |
| // CHECK-SAME: ptr noundef [[A:%.*]], ptr noundef [[B:%.*]]) #[[ATTR0]] { | |
| // CHECK-NEXT: [[ENTRY:.*:]] | |
| // CHECK-NEXT: [[A_ADDR:%.*]] = alloca ptr, align 8 | |
| // CHECK-NEXT: [[B_ADDR:%.*]] = alloca ptr, align 8 | |
| // CHECK-NEXT: store ptr [[A]], ptr [[A_ADDR]], align 8, !tbaa [[ANYPTR_TBAA6]] | |
| // CHECK-NEXT: store ptr [[B]], ptr [[B_ADDR]], align 8, !tbaa [[ANYPTR_TBAA6]] | |
| // CHECK-NEXT: [[TMP0:%.*]] = load ptr, ptr [[A_ADDR]], align 8, !tbaa [[ANYPTR_TBAA6]] | |
| // CHECK-NEXT: [[TMP1:%.*]] = load <4 x i32>, ptr [[TMP0]], align 4, !tbaa [[INT_TBAA12]] | |
| // CHECK-NEXT: [[TMP2:%.*]] = load ptr, ptr [[B_ADDR]], align 8, !tbaa [[ANYPTR_TBAA6]] | |
| // CHECK-NEXT: store <4 x i32> [[TMP1]], ptr [[TMP2]], align 4, !tbaa [[INT_TBAA12]] | |
| // CHECK-NEXT: ret void | |
| // | |
| void load_may_alias_matrix(aim_t *a, aim_t *b) { | |
| *b = *a; | |
| } | |
| //. | |
| // CHECK: [[META3:![0-9]+]] = !{!"int", [[META4:![0-9]+]], i64 0} | |
| // CHECK: [[META4]] = !{!"omnipotent char", [[META5:![0-9]+]], i64 0} | |
| // CHECK: [[META5]] = !{!"Simple C/C++ TBAA"} | |
| // CHECK: [[ANYPTR_TBAA6]] = !{[[META7:![0-9]+]], [[META7]], i64 0} | |
| // CHECK: [[META7]] = !{!"any pointer", [[META4]], i64 0} | |
| // CHECK: [[DOUBLE_TBAA8]] = !{[[META9:![0-9]+]], [[META9]], i64 0} | |
| // CHECK: [[META9]] = !{!"double", [[META4]], i64 0} | |
| // CHECK: [[FLOAT_TBAA10]] = !{[[META11:![0-9]+]], [[META11]], i64 0} | |
| // CHECK: [[META11]] = !{!"float", [[META4]], i64 0} | |
| // CHECK: [[INT_TBAA12]] = !{[[META3]], [[META3]], i64 0} | |
| // CHECK: [[DOUBLEPTR_TBAA13]] = !{[[META14:![0-9]+]], [[META14]], i64 0} | |
| // CHECK: [[META14]] = !{!"p1 double", [[META7]], i64 0} | |
| //. |