1 // REQUIRES: arm-registered-target 2 // RUN: %clang_cc1 -emit-llvm -o - -triple arm-none-linux-gnueabi %s | FileCheck %s 3 // RUN: %clang_cc1 -emit-llvm -o - -triple arm-none-linux-gnueabihf %s | FileCheck %s 4 // RUN: %clang_cc1 -emit-llvm -o - -triple arm-none-linux-gnueabi -target-feature "+soft-float" -target-feature "+soft-float-abi" %s | FileCheck %s 5 // RUN: %clang_cc1 -emit-llvm -o - -triple arm-none-linux-gnueabi -target-feature "+soft-float" %s | FileCheck %s 6 // RUN: %clang_cc1 -emit-llvm -o - -triple arm-none-eabi %s | FileCheck %s 7 // RUN: %clang_cc1 -emit-llvm -o - -triple arm-none-eabi -meabi gnu %s | FileCheck %s 8 // RUN: %clang_cc1 -emit-llvm -o - -triple arm-none-eabi %s | FileCheck %s 9 // RUN: %clang_cc1 -emit-llvm -o - -triple arm-none-eabi -target-feature "+soft-float" -target-feature "+soft-float-abi" -meabi gnu %s | FileCheck %s 10 // RUN: %clang_cc1 -emit-llvm -o - -triple arm-none-eabi -target-feature "+soft-float" -meabi gnu %s | FileCheck %s 11 // RUN: %clang_cc1 -emit-llvm -o - -triple arm-none-eabihf %s | FileCheck %s 12 // RUN: %clang_cc1 -emit-llvm -o - -triple arm-none-eabihf -meabi gnu %s | FileCheck %s 13 14 // The Runtime ABI for the ARM Architecture IHI0043 section 4.1.2 The 15 // floating-point helper functions to always use the base AAPCS (soft-float) 16 // calling convention. 17 // 18 // These helper functions such as __aeabi_fadd are not explicitly called by 19 // clang, instead they are generated by the ARMISelLowering when they are 20 // needed; clang relies on llvm to use the base AAPCS. 21 // 22 // In this test we check that clang is not directly calling the __aeabi_ 23 // functions. We rely on llvm to test that the base AAPCS is used for any 24 // __aeabi_ function from 4.1.2 that is used. 25 // 26 // When compiled to an object file with -mfloat-abi=soft each function F 27 // below should result in a call to __aeabi_F. If clang is changed to call any 28 // of these functions directly the test will need to be altered to check that 29 // arm_aapcscc is used. 30 // 31 // Note that it is only the functions in 4.1.2 that must use the base AAPCS, 32 // other runtime functions such as the _Complex helper routines are not covered. 33 34 float fadd(float a, float b) { return a + b; } 35 // CHECK-LABEL: define{{.*}} float @fadd(float noundef %a, float noundef %b) 36 // CHECK-NOT: __aeabi_fadd 37 // CHECK: %add = fadd float {{.*}}, {{.*}} 38 39 float fdiv(float a, float b) { return a / b; } 40 // CHECK-LABEL: define{{.*}} float @fdiv(float noundef %a, float noundef %b) 41 // CHECK-NOT: __aeabi_fdiv 42 // CHECK: %div = fdiv float {{.*}}, {{.*}} 43 44 float fmul(float a, float b) { return a * b; } 45 // CHECK-LABEL: define{{.*}} float @fmul(float noundef %a, float noundef %b) 46 // CHECK-NOT: __aeabi_fmul 47 // CHECK: %mul = fmul float {{.*}}, {{.*}} 48 49 float fsub(float a, float b) { return a - b; } 50 // CHECK-LABEL: define{{.*}} float @fsub(float noundef %a, float noundef %b) 51 // CHECK-NOT: __aeabi_fsub 52 // CHECK: %sub = fsub float {{.*}}, {{.*}} 53 54 int fcmpeq(float a, float b) { return a == b; } 55 // CHECK-LABEL: define{{.*}} i32 @fcmpeq(float noundef %a, float noundef %b) 56 // CHECK-NOT: __aeabi_fcmpeq 57 // CHECK: %cmp = fcmp oeq float {{.*}}, {{.*}} 58 59 int fcmplt(float a, float b) { return a < b; } 60 // CHECK-LABEL: define{{.*}} i32 @fcmplt(float noundef %a, float noundef %b) 61 // CHECK-NOT: __aeabi_fcmplt 62 // CHECK: %cmp = fcmp olt float {{.*}}, {{.*}} 63 64 int fcmple(float a, float b) { return a <= b; } 65 // CHECK-LABEL: define{{.*}} i32 @fcmple(float noundef %a, float noundef %b) 66 // CHECK-NOT: __aeabi_fcmple 67 // CHECK: %cmp = fcmp ole float {{.*}}, {{.*}} 68 69 int fcmpge(float a, float b) { return a >= b; } 70 // CHECK-LABEL: define{{.*}} i32 @fcmpge(float noundef %a, float noundef %b) 71 // CHECK-NOT: __aeabi_fcmpge 72 // CHECK: %cmp = fcmp oge float {{.*}}, {{.*}} 73 74 int fcmpgt(float a, float b) { return a > b; } 75 // CHECK-LABEL: define{{.*}} i32 @fcmpgt(float noundef %a, float noundef %b) 76 // CHECK-NOT: __aeabi_fcmpgt 77 // CHECK: %cmp = fcmp ogt float {{.*}}, {{.*}} 78 79 int fcmpun(float a, float b) { return __builtin_isunordered(a, b); } 80 // CHECK-LABEL: define{{.*}} i32 @fcmpun(float noundef %a, float noundef %b) 81 // CHECK-NOT: __aeabi_fcmpun 82 // CHECK: %cmp = fcmp uno float {{.*}}, {{.*}} 83 84 double dadd(double a, double b) { return a + b; } 85 // CHECK-LABEL: define{{.*}} double @dadd(double noundef %a, double noundef %b) 86 // CHECK-NOT: __aeabi_dadd 87 // CHECK: %add = fadd double {{.*}}, {{.*}} 88 89 double ddiv(double a, double b) { return a / b; } 90 // CHECK-LABEL: define{{.*}} double @ddiv(double noundef %a, double noundef %b) 91 // CHECK-NOT: __aeabi_ddiv 92 // CHECK: %div = fdiv double {{.*}}, {{.*}} 93 94 double dmul(double a, double b) { return a * b; } 95 // CHECK-LABEL: define{{.*}} double @dmul(double noundef %a, double noundef %b) 96 // CHECK-NOT: __aeabi_dmul 97 // CHECK: %mul = fmul double {{.*}}, {{.*}} 98 99 double dsub(double a, double b) { return a - b; } 100 // CHECK-LABEL: define{{.*}} double @dsub(double noundef %a, double noundef %b) 101 // CHECK-NOT: __aeabi_dsub 102 // CHECK: %sub = fsub double {{.*}}, {{.*}} 103 104 int dcmpeq(double a, double b) { return a == b; } 105 // CHECK-LABEL: define{{.*}} i32 @dcmpeq(double noundef %a, double noundef %b) 106 // CHECK-NOT: __aeabi_dcmpeq 107 // CHECK: %cmp = fcmp oeq double {{.*}}, {{.*}} 108 109 int dcmplt(double a, double b) { return a < b; } 110 // CHECK-LABEL: define{{.*}} i32 @dcmplt(double noundef %a, double noundef %b) 111 // CHECK-NOT: __aeabi_dcmplt 112 // CHECK: %cmp = fcmp olt double {{.*}}, {{.*}} 113 114 int dcmple(double a, double b) { return a <= b; } 115 // CHECK-LABEL: define{{.*}} i32 @dcmple(double noundef %a, double noundef %b) 116 // CHECK-NOT: __aeabi_dcmple 117 // CHECK: %cmp = fcmp ole double {{.*}}, {{.*}} 118 119 int dcmpge(double a, double b) { return a >= b; } 120 // CHECK-LABEL: define{{.*}} i32 @dcmpge(double noundef %a, double noundef %b) 121 // CHECK-NOT: __aeabi_dcmpge 122 // CHECK: %cmp = fcmp oge double {{.*}}, {{.*}} 123 124 int dcmpgt(double a, double b) { return a > b; } 125 // CHECK-LABEL: define{{.*}} i32 @dcmpgt(double noundef %a, double noundef %b) 126 // CHECK-NOT: __aeabi_dcmpgt 127 // CHECK: %cmp = fcmp ogt double {{.*}}, {{.*}} 128 129 int dcmpun(double a, double b) { return __builtin_isunordered(a, b); } 130 // CHECK-LABEL: define{{.*}} i32 @dcmpun(double noundef %a, double noundef %b) 131 // CHECK-NOT: __aeabi_dcmpun 132 // CHECK: %cmp = fcmp uno double {{.*}}, {{.*}} 133 134 int d2iz(double a) { return (int)a; } 135 // CHECK-LABEL: define{{.*}} i32 @d2iz(double noundef %a) 136 // CHECK-NOT: __aeabi_d2iz 137 // CHECK: %conv = fptosi double {{.*}} to i32 138 139 unsigned int d2uiz(double a) { return (unsigned int)a; } 140 // CHECK-LABEL: define{{.*}} i32 @d2uiz(double noundef %a) 141 // CHECK-NOT: __aeabi_d2uiz 142 // CHECK: %conv = fptoui double {{.*}} to i32 143 144 long long d2lz(double a) { return (long long)a; } 145 // CHECK-LABEL: define{{.*}} i64 @d2lz(double noundef %a) 146 // CHECK-NOT: __aeabi_d2lz 147 // CHECK: %conv = fptosi double {{.*}} to i64 148 149 unsigned long long d2ulz(double a) { return (unsigned long long)a; } 150 // CHECK-LABEL: define{{.*}} i64 @d2ulz(double noundef %a) 151 // CHECK-NOT: __aeabi_d2ulz 152 // CHECK: %conv = fptoui double {{.*}} to i64 153 154 int f2iz(float a) { return (int)a; } 155 // CHECK-LABEL: define{{.*}} i32 @f2iz(float noundef %a) 156 // CHECK-NOT: __aeabi_f2iz 157 // CHECK: %conv = fptosi float {{.*}} to i32 158 159 unsigned int f2uiz(float a) { return (unsigned int)a; } 160 // CHECK-LABEL: define{{.*}} i32 @f2uiz(float noundef %a) 161 // CHECK-NOT: __aeabi_f2uiz 162 // CHECK: %conv = fptoui float {{.*}} to i32 163 164 long long f2lz(float a) { return (long long)a; } 165 // CHECK-LABEL: define{{.*}} i64 @f2lz(float noundef %a) 166 // CHECK-NOT: __aeabi_f2lz 167 // CHECK: %conv = fptosi float {{.*}} to i64 168 169 unsigned long long f2ulz(float a) { return (unsigned long long)a; } 170 // CHECK-LABEL: define{{.*}} i64 @f2ulz(float noundef %a) 171 // CHECK-NOT: __aeabi_f2ulz 172 // CHECK: %conv = fptoui float {{.*}} to i64 173 174 float d2f(double a) { return (float)a; } 175 // CHECK-LABEL: define{{.*}} float @d2f(double noundef %a) 176 // CHECK-NOT: __aeabi_d2f 177 // CHECK: %conv = fptrunc double {{.*}} to float 178 179 double f2d(float a) { return (double)a; } 180 // CHECK-LABEL: define{{.*}} double @f2d(float noundef %a) 181 // CHECK-NOT: __aeabi_f2d 182 // CHECK: %conv = fpext float {{.*}} to double 183 184 double i2d(int a) { return (double)a; } 185 // CHECK-LABEL: define{{.*}} double @i2d(i32 noundef %a) 186 // CHECK-NOT: __aeabi_i2d 187 // CHECK: %conv = sitofp i32 {{.*}} to double 188 189 double ui2d(unsigned int a) { return (double)a; } 190 // CHECK-LABEL: define{{.*}} double @ui2d(i32 noundef %a) 191 // CHECK-NOT: __aeabi_ui2d 192 // CHECK: %conv = uitofp i32 {{.*}} to double 193 194 double l2d(long long a) { return (double)a; } 195 // CHECK-LABEL: define{{.*}} double @l2d(i64 noundef %a) 196 // CHECK-NOT: __aeabi_l2d 197 // CHECK: %conv = sitofp i64 {{.*}} to double 198 199 double ul2d(unsigned long long a) { return (unsigned long long)a; } 200 // CHECK-LABEL: define{{.*}} double @ul2d(i64 noundef %a) 201 // CHECK-NOT: __aeabi_ul2d 202 // CHECK: %conv = uitofp i64 {{.*}} to double 203 204 float i2f(int a) { return (int)a; } 205 // CHECK-LABEL: define{{.*}} float @i2f(i32 noundef %a) 206 // CHECK-NOT: __aeabi_i2f 207 // CHECK: %conv = sitofp i32 {{.*}} to float 208 209 float ui2f(unsigned int a) { return (unsigned int)a; } 210 // CHECK-LABEL: define{{.*}} float @ui2f(i32 noundef %a) 211 // CHECK-NOT: __aeabi_ui2f 212 // CHECK: %conv = uitofp i32 {{.*}} to float 213 214 float l2f(long long a) { return (long long)a; } 215 // CHECK-LABEL: define{{.*}} float @l2f(i64 noundef %a) 216 // CHECK-NOT: __aeabi_l2f 217 // CHECK: %conv = sitofp i64 {{.*}} to float 218 219 float ul2f(unsigned long long a) { return (unsigned long long)a; } 220 // CHECK-LABEL: define{{.*}} float @ul2f(i64 noundef %a) 221 // CHECK-NOT: __aeabi_ul2f 222 // CHECK: %conv = uitofp i64 {{.*}} to float 223 224 // Functions in section 4.1.2 not used by llvm and don't easily map directly to 225 // C source code. 226 // cfcmpeq 227 // cfcmple 228 // cfrcmple 229 // cdcmpeq 230 // cdcmple 231 // cdrcmple 232 // frsub 233 // drsub 234