|
| 1 | +// NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py UTC_ARGS: --version 5 |
| 2 | + |
| 3 | +// RUN: %clang_cc1 -triple=aarch64-unknown-linux-gnu -fmath-errno -O3 -emit-llvm -o - %s | FileCheck %s -check-prefixes=CHECK,NONEWSTRUCTPATHTBAA |
| 4 | +// RUN: %clang_cc1 -triple=aarch64-unknown-linux-gnu -fmath-errno -O3 -new-struct-path-tbaa -emit-llvm -o - %s | FileCheck %s -check-prefixes=CHECK,NEWSTRUCTPATHTBAA |
| 5 | + |
| 6 | +float expf(float); |
| 7 | +double remainder(double, double); |
| 8 | +double fabs(double); |
| 9 | +double frexp(double, int *exp); |
| 10 | +void sincos(float a, float *s, float *c); |
| 11 | +float _Complex cacoshf(float _Complex); |
| 12 | +float crealf(float _Complex); |
| 13 | + |
| 14 | +// Emit int TBAA metadata on FP math libcalls, which is useful for alias analysis |
| 15 | + |
| 16 | +// CHECK-LABEL: define dso_local float @test_expf( |
| 17 | +// CHECK-SAME: ptr nocapture noundef readonly [[NUM:%.*]]) local_unnamed_addr #[[ATTR0:[0-9]+]] { |
| 18 | +// CHECK-NEXT: [[ENTRY:.*:]] |
| 19 | +// CHECK-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds i8, ptr [[NUM]], i64 40 |
| 20 | +// CHECK-NEXT: [[TMP0:%.*]] = load float, ptr [[ARRAYIDX]], align 4, !tbaa [[TBAA2:![0-9]+]] |
| 21 | +// CHECK-NEXT: [[CALL:%.*]] = tail call float @expf(float noundef [[TMP0]]) #[[ATTR9:[0-9]+]], !tbaa [[TBAA6:![0-9]+]] |
| 22 | +// CHECK-NEXT: [[MUL:%.*]] = fmul float [[TMP0]], [[CALL]] |
| 23 | +// CHECK-NEXT: ret float [[MUL]] |
| 24 | +// |
| 25 | +float test_expf (float num[]) { |
| 26 | + const float expm2 = expf(num[10]); // Emit TBAA metadata on @expf |
| 27 | + float tmp = expm2 * num[10]; |
| 28 | + return tmp; |
| 29 | +} |
| 30 | + |
| 31 | +// CHECK-LABEL: define dso_local float @test_builtin_expf( |
| 32 | +// CHECK-SAME: ptr nocapture noundef readonly [[NUM:%.*]]) local_unnamed_addr #[[ATTR0]] { |
| 33 | +// CHECK-NEXT: [[ENTRY:.*:]] |
| 34 | +// CHECK-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds i8, ptr [[NUM]], i64 40 |
| 35 | +// CHECK-NEXT: [[TMP0:%.*]] = load float, ptr [[ARRAYIDX]], align 4, !tbaa [[TBAA2]] |
| 36 | +// CHECK-NEXT: [[CALL:%.*]] = tail call float @expf(float noundef [[TMP0]]) #[[ATTR9]], !tbaa [[TBAA6]] |
| 37 | +// CHECK-NEXT: [[MUL:%.*]] = fmul float [[TMP0]], [[CALL]] |
| 38 | +// CHECK-NEXT: ret float [[MUL]] |
| 39 | +// |
| 40 | +float test_builtin_expf (float num[]) { |
| 41 | + const float expm2 = __builtin_expf(num[10]); // Emit TBAA metadata on @expf |
| 42 | + float tmp = expm2 * num[10]; |
| 43 | + return tmp; |
| 44 | +} |
| 45 | + |
| 46 | +// |
| 47 | +// Negative test: fabs cannot set errno |
| 48 | +// CHECK-LABEL: define dso_local double @test_fabs( |
| 49 | +// CHECK-SAME: ptr nocapture noundef readonly [[NUM:%.*]]) local_unnamed_addr #[[ATTR3:[0-9]+]] { |
| 50 | +// CHECK-NEXT: [[ENTRY:.*:]] |
| 51 | +// CHECK-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds i8, ptr [[NUM]], i64 80 |
| 52 | +// CHECK-NEXT: [[TMP0:%.*]] = load double, ptr [[ARRAYIDX]], align 8, !tbaa [[TBAA8:![0-9]+]] |
| 53 | +// CHECK-NEXT: [[TMP1:%.*]] = tail call double @llvm.fabs.f64(double [[TMP0]]) |
| 54 | +// CHECK-NEXT: [[MUL:%.*]] = fmul double [[TMP0]], [[TMP1]] |
| 55 | +// CHECK-NEXT: ret double [[MUL]] |
| 56 | +// |
| 57 | +double test_fabs (double num[]) { |
| 58 | + const double expm2 = fabs(num[10]); // Don't emit TBAA metadata |
| 59 | + double tmp = expm2 * num[10]; |
| 60 | + return tmp; |
| 61 | +} |
| 62 | + |
| 63 | +// CHECK-LABEL: define dso_local double @test_remainder( |
| 64 | +// CHECK-SAME: ptr nocapture noundef readonly [[NUM:%.*]], double noundef [[A:%.*]]) local_unnamed_addr #[[ATTR0]] { |
| 65 | +// CHECK-NEXT: [[ENTRY:.*:]] |
| 66 | +// CHECK-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds i8, ptr [[NUM]], i64 80 |
| 67 | +// CHECK-NEXT: [[TMP0:%.*]] = load double, ptr [[ARRAYIDX]], align 8, !tbaa [[TBAA8]] |
| 68 | +// CHECK-NEXT: [[CALL:%.*]] = tail call double @remainder(double noundef [[TMP0]], double noundef [[A]]) #[[ATTR9]], !tbaa [[TBAA6]] |
| 69 | +// CHECK-NEXT: [[MUL:%.*]] = fmul double [[TMP0]], [[CALL]] |
| 70 | +// CHECK-NEXT: ret double [[MUL]] |
| 71 | +// |
| 72 | +double test_remainder (double num[], double a) { |
| 73 | + const double expm2 = remainder(num[10], a); // Emit TBAA metadata |
| 74 | + double tmp = expm2 * num[10]; |
| 75 | + return tmp; |
| 76 | +} |
| 77 | + |
| 78 | +// |
| 79 | +// TODO: frexp is not subject to any errors, but also writes to |
| 80 | +// its int pointer out argument, so it could emit int TBAA metadata. |
| 81 | +// CHECK-LABEL: define dso_local double @test_frexp( |
| 82 | +// CHECK-SAME: ptr nocapture noundef readonly [[NUM:%.*]]) local_unnamed_addr #[[ATTR5:[0-9]+]] { |
| 83 | +// CHECK-NEXT: [[ENTRY:.*:]] |
| 84 | +// CHECK-NEXT: [[E:%.*]] = alloca i32, align 4 |
| 85 | +// CHECK-NEXT: call void @llvm.lifetime.start.p0(i64 4, ptr nonnull [[E]]) #[[ATTR9]] |
| 86 | +// CHECK-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds i8, ptr [[NUM]], i64 16 |
| 87 | +// CHECK-NEXT: [[TMP0:%.*]] = load double, ptr [[ARRAYIDX]], align 8, !tbaa [[TBAA8]] |
| 88 | +// CHECK-NEXT: [[CALL:%.*]] = call double @frexp(double noundef [[TMP0]], ptr noundef nonnull [[E]]) #[[ATTR9]] |
| 89 | +// CHECK-NEXT: [[MUL:%.*]] = fmul double [[TMP0]], [[CALL]] |
| 90 | +// CHECK-NEXT: call void @llvm.lifetime.end.p0(i64 4, ptr nonnull [[E]]) #[[ATTR9]] |
| 91 | +// CHECK-NEXT: ret double [[MUL]] |
| 92 | +// |
| 93 | +double test_frexp (double num[]) { |
| 94 | + int e; |
| 95 | + double expm2 = frexp(num[2], &e); // Don't emit TBAA metadata |
| 96 | + double tmp = expm2 * num[2]; |
| 97 | + return tmp; |
| 98 | +} |
| 99 | + |
| 100 | +// |
| 101 | +// Negative test: sincos is a library function, but is not a builtin function |
| 102 | +// checked in CodeGenFunction::EmitCallExpr. |
| 103 | +// CHECK-LABEL: define dso_local float @test_sincos( |
| 104 | +// CHECK-SAME: ptr nocapture noundef readonly [[NUM:%.*]]) local_unnamed_addr #[[ATTR7:[0-9]+]] { |
| 105 | +// CHECK-NEXT: [[ENTRY:.*:]] |
| 106 | +// CHECK-NEXT: [[SIN:%.*]] = alloca float, align 4 |
| 107 | +// CHECK-NEXT: [[COS:%.*]] = alloca float, align 4 |
| 108 | +// CHECK-NEXT: call void @llvm.lifetime.start.p0(i64 4, ptr nonnull [[SIN]]) #[[ATTR9]] |
| 109 | +// CHECK-NEXT: call void @llvm.lifetime.start.p0(i64 4, ptr nonnull [[COS]]) #[[ATTR9]] |
| 110 | +// CHECK-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds i8, ptr [[NUM]], i64 8 |
| 111 | +// CHECK-NEXT: [[TMP0:%.*]] = load float, ptr [[ARRAYIDX]], align 4, !tbaa [[TBAA2]] |
| 112 | +// CHECK-NEXT: call void @sincos(float noundef [[TMP0]], ptr noundef nonnull [[SIN]], ptr noundef nonnull [[COS]]) #[[ATTR9]] |
| 113 | +// CHECK-NEXT: [[TMP1:%.*]] = load float, ptr [[SIN]], align 4, !tbaa [[TBAA2]] |
| 114 | +// CHECK-NEXT: [[TMP2:%.*]] = load float, ptr [[COS]], align 4, !tbaa [[TBAA2]] |
| 115 | +// CHECK-NEXT: [[MUL:%.*]] = fmul float [[TMP1]], [[TMP2]] |
| 116 | +// CHECK-NEXT: [[TMP3:%.*]] = load float, ptr [[ARRAYIDX]], align 4, !tbaa [[TBAA2]] |
| 117 | +// CHECK-NEXT: [[ADD:%.*]] = fadd float [[MUL]], [[TMP3]] |
| 118 | +// CHECK-NEXT: call void @llvm.lifetime.end.p0(i64 4, ptr nonnull [[COS]]) #[[ATTR9]] |
| 119 | +// CHECK-NEXT: call void @llvm.lifetime.end.p0(i64 4, ptr nonnull [[SIN]]) #[[ATTR9]] |
| 120 | +// CHECK-NEXT: ret float [[ADD]] |
| 121 | +// |
| 122 | +float test_sincos (float num[]) { |
| 123 | + float sin, cos; |
| 124 | + sincos(num[2], &sin, &cos); // Don't emit TBAA metadata |
| 125 | + float tmp = sin * cos + num[2]; |
| 126 | + return tmp; |
| 127 | +} |
| 128 | + |
| 129 | +// TODO: The builtin return a complex type |
| 130 | +// CHECK-LABEL: define dso_local float @test_cacoshf( |
| 131 | +// CHECK-SAME: ptr nocapture noundef readonly [[NUM:%.*]]) local_unnamed_addr #[[ATTR7]] { |
| 132 | +// CHECK-NEXT: [[ENTRY:.*:]] |
| 133 | +// CHECK-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds i8, ptr [[NUM]], i64 8 |
| 134 | +// CHECK-NEXT: [[TMP0:%.*]] = load float, ptr [[ARRAYIDX]], align 4, !tbaa [[TBAA2]] |
| 135 | +// CHECK-NEXT: [[DOTFCA_0_INSERT:%.*]] = insertvalue [2 x float] poison, float [[TMP0]], 0 |
| 136 | +// CHECK-NEXT: [[DOTFCA_1_INSERT:%.*]] = insertvalue [2 x float] [[DOTFCA_0_INSERT]], float 0.000000e+00, 1 |
| 137 | +// CHECK-NEXT: [[CALL:%.*]] = tail call { float, float } @cacoshf([2 x float] noundef alignstack(8) [[DOTFCA_1_INSERT]]) #[[ATTR9]] |
| 138 | +// CHECK-NEXT: [[TMP1:%.*]] = extractvalue { float, float } [[CALL]], 0 |
| 139 | +// CHECK-NEXT: [[TMP2:%.*]] = load float, ptr [[ARRAYIDX]], align 4, !tbaa [[TBAA2]] |
| 140 | +// CHECK-NEXT: [[ADD:%.*]] = fadd float [[TMP1]], [[TMP2]] |
| 141 | +// CHECK-NEXT: ret float [[ADD]] |
| 142 | +// |
| 143 | +float test_cacoshf (float num[]) { |
| 144 | + float _Complex z = cacoshf(num[2]); // Don't emit TBAA metadata |
| 145 | + float tmp = crealf(z) + num[2]; |
| 146 | + return tmp; |
| 147 | +} |
| 148 | + |
| 149 | +//. |
| 150 | +// NONEWSTRUCTPATHTBAA: [[TBAA2]] = !{[[META3:![0-9]+]], [[META3]], i64 0} |
| 151 | +// NONEWSTRUCTPATHTBAA: [[META3]] = !{!"float", [[META4:![0-9]+]], i64 0} |
| 152 | +// NONEWSTRUCTPATHTBAA: [[META4]] = !{!"omnipotent char", [[META5:![0-9]+]], i64 0} |
| 153 | +// NONEWSTRUCTPATHTBAA: [[META5]] = !{!"Simple C/C++ TBAA"} |
| 154 | +// NONEWSTRUCTPATHTBAA: [[TBAA6]] = !{[[META7:![0-9]+]], [[META7]], i64 0} |
| 155 | +// NONEWSTRUCTPATHTBAA: [[META7]] = !{!"int", [[META4]], i64 0} |
| 156 | +// NONEWSTRUCTPATHTBAA: [[TBAA8]] = !{[[META9:![0-9]+]], [[META9]], i64 0} |
| 157 | +// NONEWSTRUCTPATHTBAA: [[META9]] = !{!"double", [[META4]], i64 0} |
| 158 | +//. |
| 159 | +// NEWSTRUCTPATHTBAA: [[TBAA2]] = !{[[META3:![0-9]+]], [[META3]], i64 0, i64 4} |
| 160 | +// NEWSTRUCTPATHTBAA: [[META3]] = !{[[META4:![0-9]+]], i64 4, !"float"} |
| 161 | +// NEWSTRUCTPATHTBAA: [[META4]] = !{[[META5:![0-9]+]], i64 1, !"omnipotent char"} |
| 162 | +// NEWSTRUCTPATHTBAA: [[META5]] = !{!"Simple C/C++ TBAA"} |
| 163 | +// NEWSTRUCTPATHTBAA: [[TBAA6]] = !{[[META7:![0-9]+]], [[META7]], i64 0, i64 4} |
| 164 | +// NEWSTRUCTPATHTBAA: [[META7]] = !{[[META4]], i64 4, !"int"} |
| 165 | +// NEWSTRUCTPATHTBAA: [[TBAA8]] = !{[[META9:![0-9]+]], [[META9]], i64 0, i64 8} |
| 166 | +// NEWSTRUCTPATHTBAA: [[META9]] = !{[[META4]], i64 8, !"double"} |
| 167 | +//. |
| 168 | +//// NOTE: These prefixes are unused and the list is autogenerated. Do not add tests below this line: |
| 169 | +// NEWSTRUCTPATHTBAA: {{.*}} |
| 170 | +// NONEWSTRUCTPATHTBAA: {{.*}} |
0 commit comments