1; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py 2; RUN: llc < %s -mtriple=aarch64 | FileCheck %s --check-prefixes=CHECK,CHECK-CVT 3; RUN: llc < %s -mtriple=aarch64 -mattr=+fullfp16 | FileCheck %s --check-prefixes=CHECK,CHECK-FP16 4 5; Round towards minus infinity (fcvtmu). 6 7define i32 @testmuwh(half %a) { 8; CHECK-CVT-LABEL: testmuwh: 9; CHECK-CVT: // %bb.0: // %entry 10; CHECK-CVT-NEXT: fcvt s0, h0 11; CHECK-CVT-NEXT: frintm s0, s0 12; CHECK-CVT-NEXT: fcvt h0, s0 13; CHECK-CVT-NEXT: fcvt s0, h0 14; CHECK-CVT-NEXT: fcvtzu w0, s0 15; CHECK-CVT-NEXT: ret 16; 17; CHECK-FP16-LABEL: testmuwh: 18; CHECK-FP16: // %bb.0: // %entry 19; CHECK-FP16-NEXT: fcvtmu w0, h0 20; CHECK-FP16-NEXT: ret 21entry: 22 %r = call half @llvm.floor.f16(half %a) nounwind readnone 23 %i = call i32 @llvm.fptoui.sat.i32.f16(half %r) 24 ret i32 %i 25} 26 27define i64 @testmuxh(half %a) { 28; CHECK-CVT-LABEL: testmuxh: 29; CHECK-CVT: // %bb.0: // %entry 30; CHECK-CVT-NEXT: fcvt s0, h0 31; CHECK-CVT-NEXT: frintm s0, s0 32; CHECK-CVT-NEXT: fcvt h0, s0 33; CHECK-CVT-NEXT: fcvt s0, h0 34; CHECK-CVT-NEXT: fcvtzu x0, s0 35; CHECK-CVT-NEXT: ret 36; 37; CHECK-FP16-LABEL: testmuxh: 38; CHECK-FP16: // %bb.0: // %entry 39; CHECK-FP16-NEXT: fcvtmu x0, h0 40; CHECK-FP16-NEXT: ret 41entry: 42 %r = call half @llvm.floor.f16(half %a) nounwind readnone 43 %i = call i64 @llvm.fptoui.sat.i64.f16(half %r) 44 ret i64 %i 45} 46 47define i32 @testmuws(float %a) { 48; CHECK-LABEL: testmuws: 49; CHECK: // %bb.0: // %entry 50; CHECK-NEXT: fcvtmu w0, s0 51; CHECK-NEXT: ret 52entry: 53 %r = call float @floorf(float %a) nounwind readnone 54 %i = call i32 @llvm.fptoui.sat.i32.f32(float %r) 55 ret i32 %i 56} 57 58define i64 @testmuxs(float %a) { 59; CHECK-LABEL: testmuxs: 60; CHECK: // %bb.0: // %entry 61; CHECK-NEXT: fcvtmu x0, s0 62; CHECK-NEXT: ret 63entry: 64 %r = call float @floorf(float %a) nounwind readnone 65 %i = call i64 @llvm.fptoui.sat.i64.f32(float %r) 66 ret i64 %i 67} 68 69define i32 @testmuwd(double %a) { 70; CHECK-LABEL: testmuwd: 71; CHECK: // %bb.0: // %entry 72; CHECK-NEXT: fcvtmu w0, d0 73; CHECK-NEXT: ret 74entry: 75 %r = call double @floor(double %a) nounwind readnone 76 %i = call i32 @llvm.fptoui.sat.i32.f64(double %r) 77 ret i32 %i 78} 79 80define i64 @testmuxd(double %a) { 81; CHECK-LABEL: testmuxd: 82; CHECK: // %bb.0: // %entry 83; CHECK-NEXT: fcvtmu x0, d0 84; CHECK-NEXT: ret 85entry: 86 %r = call double @floor(double %a) nounwind readnone 87 %i = call i64 @llvm.fptoui.sat.i64.f64(double %r) 88 ret i64 %i 89} 90 91; Round towards plus infinity (fcvtpu). 92 93define i32 @testpuwh(half %a) { 94; CHECK-CVT-LABEL: testpuwh: 95; CHECK-CVT: // %bb.0: // %entry 96; CHECK-CVT-NEXT: fcvt s0, h0 97; CHECK-CVT-NEXT: frintp s0, s0 98; CHECK-CVT-NEXT: fcvt h0, s0 99; CHECK-CVT-NEXT: fcvt s0, h0 100; CHECK-CVT-NEXT: fcvtzu w0, s0 101; CHECK-CVT-NEXT: ret 102; 103; CHECK-FP16-LABEL: testpuwh: 104; CHECK-FP16: // %bb.0: // %entry 105; CHECK-FP16-NEXT: fcvtpu w0, h0 106; CHECK-FP16-NEXT: ret 107entry: 108 %r = call half @llvm.ceil.f16(half %a) nounwind readnone 109 %i = call i32 @llvm.fptoui.sat.i32.f16(half %r) 110 ret i32 %i 111} 112 113define i64 @testpuxh(half %a) { 114; CHECK-CVT-LABEL: testpuxh: 115; CHECK-CVT: // %bb.0: // %entry 116; CHECK-CVT-NEXT: fcvt s0, h0 117; CHECK-CVT-NEXT: frintp s0, s0 118; CHECK-CVT-NEXT: fcvt h0, s0 119; CHECK-CVT-NEXT: fcvt s0, h0 120; CHECK-CVT-NEXT: fcvtzu x0, s0 121; CHECK-CVT-NEXT: ret 122; 123; CHECK-FP16-LABEL: testpuxh: 124; CHECK-FP16: // %bb.0: // %entry 125; CHECK-FP16-NEXT: fcvtpu x0, h0 126; CHECK-FP16-NEXT: ret 127entry: 128 %r = call half @llvm.ceil.f16(half %a) nounwind readnone 129 %i = call i64 @llvm.fptoui.sat.i64.f16(half %r) 130 ret i64 %i 131} 132 133define i32 @testpuws(float %a) { 134; CHECK-LABEL: testpuws: 135; CHECK: // %bb.0: // %entry 136; CHECK-NEXT: fcvtpu w0, s0 137; CHECK-NEXT: ret 138entry: 139 %r = call float @ceilf(float %a) nounwind readnone 140 %i = call i32 @llvm.fptoui.sat.i32.f32(float %r) 141 ret i32 %i 142} 143 144define i64 @testpuxs(float %a) { 145; CHECK-LABEL: testpuxs: 146; CHECK: // %bb.0: // %entry 147; CHECK-NEXT: fcvtpu x0, s0 148; CHECK-NEXT: ret 149entry: 150 %r = call float @ceilf(float %a) nounwind readnone 151 %i = call i64 @llvm.fptoui.sat.i64.f32(float %r) 152 ret i64 %i 153} 154 155define i32 @testpuwd(double %a) { 156; CHECK-LABEL: testpuwd: 157; CHECK: // %bb.0: // %entry 158; CHECK-NEXT: fcvtpu w0, d0 159; CHECK-NEXT: ret 160entry: 161 %r = call double @ceil(double %a) nounwind readnone 162 %i = call i32 @llvm.fptoui.sat.i32.f64(double %r) 163 ret i32 %i 164} 165 166define i64 @testpuxd(double %a) { 167; CHECK-LABEL: testpuxd: 168; CHECK: // %bb.0: // %entry 169; CHECK-NEXT: fcvtpu x0, d0 170; CHECK-NEXT: ret 171entry: 172 %r = call double @ceil(double %a) nounwind readnone 173 %i = call i64 @llvm.fptoui.sat.i64.f64(double %r) 174 ret i64 %i 175} 176 177; Round towards zero (fcvtzu). 178 179define i32 @testzuwh(half %a) { 180; CHECK-CVT-LABEL: testzuwh: 181; CHECK-CVT: // %bb.0: // %entry 182; CHECK-CVT-NEXT: fcvt s0, h0 183; CHECK-CVT-NEXT: frintz s0, s0 184; CHECK-CVT-NEXT: fcvt h0, s0 185; CHECK-CVT-NEXT: fcvt s0, h0 186; CHECK-CVT-NEXT: fcvtzu w0, s0 187; CHECK-CVT-NEXT: ret 188; 189; CHECK-FP16-LABEL: testzuwh: 190; CHECK-FP16: // %bb.0: // %entry 191; CHECK-FP16-NEXT: fcvtzu w0, h0 192; CHECK-FP16-NEXT: ret 193entry: 194 %r = call half @llvm.trunc.f16(half %a) nounwind readnone 195 %i = call i32 @llvm.fptoui.sat.i32.f16(half %r) 196 ret i32 %i 197} 198 199define i64 @testzuxh(half %a) { 200; CHECK-CVT-LABEL: testzuxh: 201; CHECK-CVT: // %bb.0: // %entry 202; CHECK-CVT-NEXT: fcvt s0, h0 203; CHECK-CVT-NEXT: frintz s0, s0 204; CHECK-CVT-NEXT: fcvt h0, s0 205; CHECK-CVT-NEXT: fcvt s0, h0 206; CHECK-CVT-NEXT: fcvtzu x0, s0 207; CHECK-CVT-NEXT: ret 208; 209; CHECK-FP16-LABEL: testzuxh: 210; CHECK-FP16: // %bb.0: // %entry 211; CHECK-FP16-NEXT: fcvtzu x0, h0 212; CHECK-FP16-NEXT: ret 213entry: 214 %r = call half @llvm.trunc.f16(half %a) nounwind readnone 215 %i = call i64 @llvm.fptoui.sat.i64.f16(half %r) 216 ret i64 %i 217} 218 219define i32 @testzuws(float %a) { 220; CHECK-LABEL: testzuws: 221; CHECK: // %bb.0: // %entry 222; CHECK-NEXT: fcvtzu w0, s0 223; CHECK-NEXT: ret 224entry: 225 %r = call float @truncf(float %a) nounwind readnone 226 %i = call i32 @llvm.fptoui.sat.i32.f32(float %r) 227 ret i32 %i 228} 229 230define i64 @testzuxs(float %a) { 231; CHECK-LABEL: testzuxs: 232; CHECK: // %bb.0: // %entry 233; CHECK-NEXT: fcvtzu x0, s0 234; CHECK-NEXT: ret 235entry: 236 %r = call float @truncf(float %a) nounwind readnone 237 %i = call i64 @llvm.fptoui.sat.i64.f32(float %r) 238 ret i64 %i 239} 240 241define i32 @testzuwd(double %a) { 242; CHECK-LABEL: testzuwd: 243; CHECK: // %bb.0: // %entry 244; CHECK-NEXT: fcvtzu w0, d0 245; CHECK-NEXT: ret 246entry: 247 %r = call double @trunc(double %a) nounwind readnone 248 %i = call i32 @llvm.fptoui.sat.i32.f64(double %r) 249 ret i32 %i 250} 251 252define i64 @testzuxd(double %a) { 253; CHECK-LABEL: testzuxd: 254; CHECK: // %bb.0: // %entry 255; CHECK-NEXT: fcvtzu x0, d0 256; CHECK-NEXT: ret 257entry: 258 %r = call double @trunc(double %a) nounwind readnone 259 %i = call i64 @llvm.fptoui.sat.i64.f64(double %r) 260 ret i64 %i 261} 262 263; Round to nearest, ties away from zero (fcvtau). 264 265define i32 @testauwh(half %a) { 266; CHECK-CVT-LABEL: testauwh: 267; CHECK-CVT: // %bb.0: // %entry 268; CHECK-CVT-NEXT: fcvt s0, h0 269; CHECK-CVT-NEXT: frinta s0, s0 270; CHECK-CVT-NEXT: fcvt h0, s0 271; CHECK-CVT-NEXT: fcvt s0, h0 272; CHECK-CVT-NEXT: fcvtzu w0, s0 273; CHECK-CVT-NEXT: ret 274; 275; CHECK-FP16-LABEL: testauwh: 276; CHECK-FP16: // %bb.0: // %entry 277; CHECK-FP16-NEXT: fcvtau w0, h0 278; CHECK-FP16-NEXT: ret 279entry: 280 %r = call half @llvm.round.f16(half %a) nounwind readnone 281 %i = call i32 @llvm.fptoui.sat.i32.f16(half %r) 282 ret i32 %i 283} 284 285define i64 @testauxh(half %a) { 286; CHECK-CVT-LABEL: testauxh: 287; CHECK-CVT: // %bb.0: // %entry 288; CHECK-CVT-NEXT: fcvt s0, h0 289; CHECK-CVT-NEXT: frinta s0, s0 290; CHECK-CVT-NEXT: fcvt h0, s0 291; CHECK-CVT-NEXT: fcvt s0, h0 292; CHECK-CVT-NEXT: fcvtzu x0, s0 293; CHECK-CVT-NEXT: ret 294; 295; CHECK-FP16-LABEL: testauxh: 296; CHECK-FP16: // %bb.0: // %entry 297; CHECK-FP16-NEXT: fcvtau x0, h0 298; CHECK-FP16-NEXT: ret 299entry: 300 %r = call half @llvm.round.f16(half %a) nounwind readnone 301 %i = call i64 @llvm.fptoui.sat.i64.f16(half %r) 302 ret i64 %i 303} 304 305define i32 @testauws(float %a) { 306; CHECK-LABEL: testauws: 307; CHECK: // %bb.0: // %entry 308; CHECK-NEXT: fcvtau w0, s0 309; CHECK-NEXT: ret 310entry: 311 %r = call float @roundf(float %a) nounwind readnone 312 %i = call i32 @llvm.fptoui.sat.i32.f32(float %r) 313 ret i32 %i 314} 315 316define i64 @testauxs(float %a) { 317; CHECK-LABEL: testauxs: 318; CHECK: // %bb.0: // %entry 319; CHECK-NEXT: fcvtau x0, s0 320; CHECK-NEXT: ret 321entry: 322 %r = call float @roundf(float %a) nounwind readnone 323 %i = call i64 @llvm.fptoui.sat.i64.f32(float %r) 324 ret i64 %i 325} 326 327define i32 @testauwd(double %a) { 328; CHECK-LABEL: testauwd: 329; CHECK: // %bb.0: // %entry 330; CHECK-NEXT: fcvtau w0, d0 331; CHECK-NEXT: ret 332entry: 333 %r = call double @round(double %a) nounwind readnone 334 %i = call i32 @llvm.fptoui.sat.i32.f64(double %r) 335 ret i32 %i 336} 337 338define i64 @testauxd(double %a) { 339; CHECK-LABEL: testauxd: 340; CHECK: // %bb.0: // %entry 341; CHECK-NEXT: fcvtau x0, d0 342; CHECK-NEXT: ret 343entry: 344 %r = call double @round(double %a) nounwind readnone 345 %i = call i64 @llvm.fptoui.sat.i64.f64(double %r) 346 ret i64 %i 347} 348 349declare i32 @llvm.fptoui.sat.i32.f16 (half) 350declare i64 @llvm.fptoui.sat.i64.f16 (half) 351declare i32 @llvm.fptoui.sat.i32.f32 (float) 352declare i64 @llvm.fptoui.sat.i64.f32 (float) 353declare i32 @llvm.fptoui.sat.i32.f64 (double) 354declare i64 @llvm.fptoui.sat.i64.f64 (double) 355 356declare half @llvm.floor.f16(half) nounwind readnone 357declare half @llvm.ceil.f16(half) nounwind readnone 358declare half @llvm.trunc.f16(half) nounwind readnone 359declare half @llvm.round.f16(half) nounwind readnone 360declare float @floorf(float) nounwind readnone 361declare float @ceilf(float) nounwind readnone 362declare float @truncf(float) nounwind readnone 363declare float @roundf(float) nounwind readnone 364declare double @floor(double) nounwind readnone 365declare double @ceil(double) nounwind readnone 366declare double @trunc(double) nounwind readnone 367declare double @round(double) nounwind readnone 368