brintos

brintos / llvm-project-archived public Read only

0
0
Text · 34.2 KiB · 7a1d5dd Raw
1057 lines · plain
1; SOFT:2; RUN: llc < %s -mtriple=arm-none-eabi -float-abi=soft     | FileCheck %s --check-prefixes=CHECK,CHECK-SOFT3; RUN: llc < %s -mtriple=thumb-none-eabi -float-abi=soft   | FileCheck %s --check-prefixes=CHECK,CHECK-SOFT4; RUN: llc < %s -mtriple=thumbv8.1m.main-none-eabi -mattr=+mve | FileCheck %s --check-prefixes=CHECK,CHECK-SOFT5; RUN: llc < %s -mtriple=thumbv8.1m.main-none-eabi -float-abi=soft -mattr=+mve | FileCheck %s --check-prefixes=CHECK,CHECK-SOFT6 7; SOFTFP:8; RUN: llc < %s -mtriple=arm-none-eabi -mattr=+vfp3        | FileCheck %s --check-prefixes=CHECK,CHECK-SOFTFP-VFP39; RUN: llc < %s -mtriple=arm-none-eabi -mattr=+vfp4        | FileCheck %s --check-prefixes=CHECK,CHECK-SOFTFP-FP16,CHECK-SOFTFP-FP16-A3210; RUN: llc < %s -mtriple=arm-none-eabi -mattr=+fullfp16,+fp64    | FileCheck %s --check-prefixes=CHECK,CHECK-SOFTFP-FULLFP1611 12; RUN: llc < %s -mtriple=thumbv7-none-eabi -mattr=+vfp3        | FileCheck %s --check-prefixes=CHECK,CHECK-SOFTFP-VFP313; RUN: llc < %s -mtriple=thumbv7-none-eabi -mattr=+vfp4        | FileCheck %s --check-prefixes=CHECK,CHECK-SOFTFP-FP16,CHECK-SOFTFP-FP16-T3214; RUN: llc < %s -mtriple=thumbv7-none-eabi -mattr=+fullfp16,+fp64    | FileCheck %s --check-prefixes=CHECK,CHECK-SOFTFP-FULLFP1615 16; Test fast-isel17; RUN: llc < %s -mtriple=arm-none-eabi -mattr=+fullfp16,+fp64 -O0 | FileCheck %s --check-prefixes=CHECK-SPILL-RELOAD18; RUN: llc < %s -mtriple=thumbv7-none-eabi -mattr=+fullfp16,+fp64 -O0 | FileCheck %s --check-prefixes=CHECK-SPILL-RELOAD19 20; HARD:21; RUN: llc < %s -mtriple=arm-none-eabihf -mattr=+vfp3      | FileCheck %s --check-prefixes=CHECK,CHECK-HARDFP-VFP322; RUN: llc < %s -mtriple=arm-none-eabihf -mattr=+vfp4      | FileCheck %s --check-prefixes=CHECK,CHECK-HARDFP-FP1623; RUN: llc < %s -mtriple=arm-none-eabihf -mattr=+fullfp16,+fp64  | FileCheck %s --check-prefixes=CHECK,CHECK-HARDFP-FULLFP1624 25; RUN: llc < %s -mtriple=thumbv7-none-eabihf -mattr=+vfp3      | FileCheck %s --check-prefixes=CHECK,CHECK-HARDFP-VFP326; RUN: llc < %s -mtriple=thumbv7-none-eabihf -mattr=+vfp4      | FileCheck %s --check-prefixes=CHECK,CHECK-HARDFP-FP1627; RUN: llc < %s -mtriple=thumbv7-none-eabihf -mattr=+fullfp16,fp64  | FileCheck %s --check-prefixes=CHECK,CHECK-HARDFP-FULLFP1628 29; FP-CONTRACT=FAST30; RUN: llc < %s -mtriple=arm-none-eabihf -mattr=+fullfp16,+fp64 -fp-contract=fast | FileCheck %s --check-prefixes=CHECK,CHECK-HARDFP-FULLFP16-FAST31; RUN: llc < %s -mtriple=thumbv7-none-eabihf -mattr=+fullfp16,+fp64 -fp-contract=fast | FileCheck %s --check-prefixes=CHECK,CHECK-HARDFP-FULLFP16-FAST32 33; TODO: we can't pass half-precision arguments as "half" types yet. We do34; that for the time being by passing "float %f.coerce" and the necessary35; bitconverts/truncates. But when we can pass half types, we do want to use36; and test that here.37 38define float @RetValBug(float %A.coerce) {39entry:40  ret float undef41; Check thatLowerReturn can handle undef nodes (i.e. nodes which do not have42; any operands) when FullFP16 is enabled.43;44; CHECK-LABEL:            RetValBug:45; CHECK-HARDFP-FULLFP16:  {{.*}} lr46}47 48; 2. VADD49define float @Add(float %a.coerce, float %b.coerce) {50entry:51  %0 = bitcast float %a.coerce to i3252  %tmp.0.extract.trunc = trunc i32 %0 to i1653  %1 = bitcast i16 %tmp.0.extract.trunc to half54  %2 = bitcast float %b.coerce to i3255  %tmp1.0.extract.trunc = trunc i32 %2 to i1656  %3 = bitcast i16 %tmp1.0.extract.trunc to half57  %add = fadd half %1, %358  %4 = bitcast half %add to i1659  %tmp4.0.insert.ext = zext i16 %4 to i3260  %5 = bitcast i32 %tmp4.0.insert.ext to float61  ret float %562 63; CHECK-LABEL: Add:64 65; CHECK-SOFT:  bl  __aeabi_h2f66; CHECK-SOFT:  bl  __aeabi_h2f67; CHECK-SOFT:  bl  __aeabi_fadd68; CHECK-SOFT:  bl  __aeabi_f2h69 70; CHECK-SOFTFP-VFP3:  bl  __aeabi_h2f71; CHECK-SOFTFP-VFP3:  bl  __aeabi_h2f72; CHECK-SOFTFP-VFP3:  vadd.f3273; CHECK-SOFTFP-VFP3:  bl  __aeabi_f2h74 75; CHECK-SOFTFP-FP16-DAG:  vmov          [[S0:s[0-9]]], r076; CHECK-SOFTFP-FP16-DAG:  vmov          [[S2:s[0-9]]], r177; CHECK-SOFTFP-FP16-DAG:  vcvtb.f32.f16 [[S0]], [[S0]]78; CHECK-SOFTFP-FP16-DAG:  vcvtb.f32.f16 [[S2]], [[S2]]79; CHECK-SOFTFP-FP16:  vadd.f32      [[S0]], [[S0]], [[S2]]80; CHECK-SOFTFP-FP16:  vcvtb.f16.f32 [[S0]], [[S0]]81; CHECK-SOFTFP-FP16:  vmov  r0, s082 83; CHECK-SOFTFP-FULLFP16:       vmov.f16  [[S0:s[0-9]]], r184; CHECK-SOFTFP-FULLFP16:       vmov.f16  [[S2:s[0-9]]], r085; CHECK-SOFTFP-FULLFP16:       vadd.f16  [[S0]], [[S2]], [[S0]]86; CHECK-SOFTFP-FULLFP16-NEXT:  vmov.f16  r0, s087 88; CHECK-HARDFP-VFP3:  vmov r89; CHECK-HARDFP-VFP3:  vmov.f32 s90; CHECK-HARDFP-VFP3:  bl  __aeabi_h2f91; CHECK-HARDFP-VFP3:  bl  __aeabi_h2f92; CHECK-HARDFP-VFP3:  vadd.f3293; CHECK-HARDFP-VFP3:  bl  __aeabi_f2h94; CHECK-HARDFP-VFP3:  vmov  s0, r095 96; CHECK-HARDFP-FP16:  vcvtb.f32.f16 [[S2:s[0-9]]], s197; CHECK-HARDFP-FP16:  vcvtb.f32.f16 [[S0:s[0-9]]], s098; CHECK-HARDFP-FP16:  vadd.f32  [[S0]], [[S0]], [[S2]]99; CHECK-HARDFP-FP16:  vcvtb.f16.f32 [[S0]], [[S0]]100 101; CHECK-HARDFP-FULLFP16:       vadd.f16  s0, s0, s1102}103 104; 3. VCMP105define zeroext i1 @VCMP1(float %F.coerce, float %G.coerce) {106entry:107  %0 = bitcast float %F.coerce to i32108  %tmp.0.extract.trunc = trunc i32 %0 to i16109  %1 = bitcast i16 %tmp.0.extract.trunc to half110  %2 = bitcast float %G.coerce to i32111  %tmp1.0.extract.trunc = trunc i32 %2 to i16112  %3 = bitcast i16 %tmp1.0.extract.trunc to half113  %cmp = fcmp une half %1, %3114  ret i1 %cmp115 116; CHECK-LABEL:            VCMP1:117 118; CHECK-SOFT:             bl  __aeabi_fcmpeq119 120; CHECK-SOFTFP-VFP3:      bl  __aeabi_h2f121; CHECK-SOFTFP-VFP3:      bl  __aeabi_h2f122; CHECK-SOFTFP-VFP3:      vcmp.f32 s{{.}}, s{{.}}123 124; CHECK-SOFTFP-FP16:      vcvtb.f32.f16 s{{.}}, s{{.}}125; CHECK-SOFTFP-FP16:      vcvtb.f32.f16 s{{.}}, s{{.}}126; CHECK-SOFTFP-FP16:      vcmp.f32 s{{.}}, s{{.}}127 128; CHECK-SOFTFP-FULLFP16:  vmov.f16  [[S2:s[0-9]]], r0129; CHECK-SOFTFP-FULLFP16:  vmov.f16 [[S0:s[0-9]]], r1130; CHECK-SOFTFP-FULLFP16:  vcmp.f16 [[S2]], [[S0]]131 132; CHECK-HARDFP-FULLFP16-NOT:  vmov.f16  s{{.}}, r0133; CHECK-HARDFP-FULLFP16-NOT:  vmov.f16  s{{.}}, r1134; CHECK-HARDFP-FULLFP16:      vcmp.f16  s0, s1135}136 137; Check VCMPZH138define zeroext i1 @VCMP2(float %F.coerce) {139entry:140  %0 = bitcast float %F.coerce to i32141  %tmp.0.extract.trunc = trunc i32 %0 to i16142  %1 = bitcast i16 %tmp.0.extract.trunc to half143  %cmp = fcmp une half %1, 0.000000e+00144  ret i1 %cmp145 146; CHECK-LABEL:             VCMP2:147 148; CHECK-SOFT:              bl __aeabi_fcmpeq149; CHECK-SOFTFP-FP16:       vcmp.f32        s0, #0150; CHECK-SOFTFP-FULLFP16:   vcmp.f16        s0, #0151; CHECK-HARDFP-FULLFP16:   vcmp.f16        s0, #0152}153 154; 4. VCMPE155define i32 @VCMPE1(float %F.coerce) {156entry:157  %0 = bitcast float %F.coerce to i32158  %tmp.0.extract.trunc = trunc i32 %0 to i16159  %1 = bitcast i16 %tmp.0.extract.trunc to half160  %tmp = fcmp olt half %1, 0.000000e+00161  %tmp1 = zext i1 %tmp to i32162  ret i32 %tmp1163 164; CHECK-LABEL:             VCMPE1:165 166; CHECK-SOFT:              bl  __aeabi_fcmplt167; CHECK-SOFTFP-FP16:       vcmp.f32 s0, #0168; CHECK-SOFTFP-FULLFP16:   vcmp.f16 s0, #0169; CHECK-HARDFP-FULLFP16:   vcmp.f16 s0, #0170}171 172define i32 @VCMPE2(float %F.coerce, float %G.coerce) {173entry:174  %0 = bitcast float %F.coerce to i32175  %tmp.0.extract.trunc = trunc i32 %0 to i16176  %1 = bitcast i16 %tmp.0.extract.trunc to half177  %2 = bitcast float %G.coerce to i32178  %tmp.1.extract.trunc = trunc i32 %2 to i16179  %3 = bitcast i16 %tmp.1.extract.trunc to half180  %tmp = fcmp olt half %1, %3181  %tmp1 = zext i1 %tmp to i32182  ret i32 %tmp1183 184; CHECK-LABEL:  VCMPE2:185 186; CHECK-SOFT:              bl  __aeabi_fcmplt187; CHECK-SOFTFP-FP16:       vcmp.f32 s{{.}}, s{{.}}188; CHECK-SOFTFP-FULLFP16:   vcmp.f16 s{{.}}, s{{.}}189; CHECK-HARDFP-FULLFP16:   vcmp.f16 s{{.}}, s{{.}}190}191 192; Test lowering of BR_CC193define hidden i32 @VCMPBRCC() {194entry:195  %f = alloca half, align 2196  br label %for.cond197 198for.cond:199  %0 = load half, ptr %f, align 2200  %cmp = fcmp nnan ninf nsz ole half %0, 0xH6800201  br i1 %cmp, label %for.body, label %for.end202 203for.body:204  ret i32 1205 206for.end:207  ret i32 0208 209; CHECK-LABEL:            VCMPBRCC:210 211; CHECK-SOFT:             bl  __aeabi_fcmp{{gt|le}}212; CHECK-SOFT:             cmp r0, #{{0|1}}213 214; CHECK-SOFTFP-FP16:      vcvtb.f32.f16 [[S2:s[0-9]]], [[S2]]215; CHECK-SOFTFP-FP16:      vcmp.f32 [[S2]], s0216; CHECK-SOFTFP-FP16:      vmrs  APSR_nzcv, fpscr217 218; CHECK-SOFTFP-FULLFP16:  vcmp.f16 s{{.}}, s{{.}}219; CHECK-SOFTFP-FULLFP16:  vmrs  APSR_nzcv, fpscr220}221 222; 5. VCVT (between floating-point and fixed-point)223; Only assembly/disassembly support224 225; 6. VCVT (between floating-point and integer, both directions)226define i32 @fptosi(i32 %A.coerce) {227entry:228  %tmp.0.extract.trunc = trunc i32 %A.coerce to i16229  %0 = bitcast i16 %tmp.0.extract.trunc to half230  %conv = fptosi half %0 to i32231  ret i32 %conv232 233; CHECK-LABEL:                 fptosi:234 235; CHECK-HARDFP-FULLFP16:       vmov.f16  s0, r0236; CHECK-HARDFP-FULLFP16-NEXT:  vcvt.s32.f16  s0, s0237; CHECK-HARDFP-FULLFP16-NEXT:  vmov  r0, s0238}239 240define i32 @fptoui(i32 %A.coerce) {241entry:242  %tmp.0.extract.trunc = trunc i32 %A.coerce to i16243  %0 = bitcast i16 %tmp.0.extract.trunc to half244  %conv = fptoui half %0 to i32245  ret i32 %conv246 247; CHECK-HARDFP-FULLFP16:       vcvt.u32.f16  s0, s0248; CHECK-HARDFP-FULLFP16-NEXT:  vmov  r0, s0249}250 251define float @UintToH(i32 %a, i32 %b) {252entry:253  %0 = uitofp i32 %a to half254  %1 = bitcast half %0 to i16255  %tmp0.insert.ext = zext i16 %1 to i32256  %2 = bitcast i32 %tmp0.insert.ext to float257  ret float %2258 259; CHECK-LABEL:                 UintToH:260 261; CHECK-HARDFP-FULLFP16:       vmov  s0, r0262; CHECK-HARDFP-FULLFP16-NEXT:  vcvt.f16.u32  s0, s0263}264 265define float @SintToH(i32 %a, i32 %b) {266entry:267  %0 = sitofp i32 %a to half268  %1 = bitcast half %0 to i16269  %tmp0.insert.ext = zext i16 %1 to i32270  %2 = bitcast i32 %tmp0.insert.ext to float271  ret float %2272 273; CHECK-LABEL:                 SintToH:274 275; CHECK-HARDFP-FULLFP16:       vmov  s0, r0276; CHECK-HARDFP-FULLFP16-NEXT:  vcvt.f16.s32  s0, s0277}278 279define i32 @f2h(float %f) {280entry:281  %conv = fptrunc float %f to half282  %0 = bitcast half %conv to i16283  %tmp.0.insert.ext = zext i16 %0 to i32284  ret i32 %tmp.0.insert.ext285 286; CHECK-LABEL:            f2h:287; CHECK-HARDFP-FULLFP16:  vcvtb.f16.f32 s0, s0288}289 290define float @h2f(i32 %h.coerce) {291entry:292  %tmp.0.extract.trunc = trunc i32 %h.coerce to i16293  %0 = bitcast i16 %tmp.0.extract.trunc to half294  %conv = fpext half %0 to float295  ret float %conv296 297; CHECK-LABEL:            h2f:298; CHECK-HARDFP-FULLFP16:  vcvtb.f32.f16 s0, s0299}300 301 302define double @h2d(i32 %h.coerce) {303entry:304  %tmp.0.extract.trunc = trunc i32 %h.coerce to i16305  %0 = bitcast i16 %tmp.0.extract.trunc to half306  %conv = fpext half %0 to double307  ret double %conv308 309; CHECK-LABEL:            h2d:310; CHECK-HARDFP-FULLFP16:  vcvtb.f64.f16 d{{.*}}, s{{.}}311}312 313define i32 @d2h(double %d) {314entry:315  %conv = fptrunc double %d to half316  %0 = bitcast half %conv to i16317  %tmp.0.insert.ext = zext i16 %0 to i32318  ret i32 %tmp.0.insert.ext319 320; CHECK-LABEL:            d2h:321; CHECK-HARDFP-FULLFP16:  vcvtb.f16.f64 s0, d{{.*}}322}323 324; TODO:325; 7.  VCVTA326; 8.  VCVTM327; 9.  VCVTN328; 10. VCVTP329; 11. VCVTR330 331; 12. VDIV332define float @Div(float %a.coerce, float %b.coerce) {333entry:334  %0 = bitcast float %a.coerce to i32335  %tmp.0.extract.trunc = trunc i32 %0 to i16336  %1 = bitcast i16 %tmp.0.extract.trunc to half337  %2 = bitcast float %b.coerce to i32338  %tmp1.0.extract.trunc = trunc i32 %2 to i16339  %3 = bitcast i16 %tmp1.0.extract.trunc to half340  %add = fdiv half %1, %3341  %4 = bitcast half %add to i16342  %tmp4.0.insert.ext = zext i16 %4 to i32343  %5 = bitcast i32 %tmp4.0.insert.ext to float344  ret float %5345 346; CHECK-LABEL:  Div:347 348; CHECK-SOFT:  bl  __aeabi_h2f349; CHECK-SOFT:  bl  __aeabi_h2f350; CHECK-SOFT:  bl  __aeabi_fdiv351; CHECK-SOFT:  bl  __aeabi_f2h352 353; CHECK-SOFTFP-VFP3:  bl  __aeabi_h2f354; CHECK-SOFTFP-VFP3:  bl  __aeabi_h2f355; CHECK-SOFTFP-VFP3:  vdiv.f32356; CHECK-SOFTFP-VFP3:  bl  __aeabi_f2h357 358; CHECK-SOFTFP-FP16-DAG:  vmov          [[S0:s[0-9]]], r0359; CHECK-SOFTFP-FP16-DAG:  vmov          [[S2:s[0-9]]], r1360; CHECK-SOFTFP-FP16-DAG:  vcvtb.f32.f16 [[S0]], [[S0]]361; CHECK-SOFTFP-FP16-DAG:  vcvtb.f32.f16 [[S2]], [[S2]]362; CHECK-SOFTFP-FP16:  vdiv.f32      [[S0]], [[S0]], [[S2]]363; CHECK-SOFTFP-FP16:  vcvtb.f16.f32 [[S0]], [[S0]]364; CHECK-SOFTFP-FP16:  vmov  r0, s0365 366; CHECK-SOFTFP-FULLFP16:       vmov.f16  [[S0:s[0-9]]], r1367; CHECK-SOFTFP-FULLFP16:       vmov.f16  [[S2:s[0-9]]], r0368; CHECK-SOFTFP-FULLFP16:       vdiv.f16  [[S0]], [[S2]], [[S0]]369; CHECK-SOFTFP-FULLFP16-NEXT:  vmov.f16  r0, s0370 371; CHECK-HARDFP-VFP3:  vmov r372; CHECK-HARDFP-VFP3:  vmov.f32 s373; CHECK-HARDFP-VFP3:  bl  __aeabi_h2f374; CHECK-HARDFP-VFP3:  bl  __aeabi_h2f375; CHECK-HARDFP-VFP3:  vdiv.f32376; CHECK-HARDFP-VFP3:  bl  __aeabi_f2h377; CHECK-HARDFP-VFP3:  vmov  s0, r0378 379; CHECK-HARDFP-FP16:  vcvtb.f32.f16 [[S2:s[0-9]]], s1380; CHECK-HARDFP-FP16:  vcvtb.f32.f16 [[S0:s[0-9]]], s0381; CHECK-HARDFP-FP16:  vdiv.f32  [[S0]], [[S0]], [[S2]]382; CHECK-HARDFP-FP16:  vcvtb.f16.f32 [[S0]], [[S0]]383 384; CHECK-HARDFP-FULLFP16:       vdiv.f16  s0, s0, s1385}386 387; 13. VFMA388define float @VFMA(float %a.coerce, float %b.coerce, float %c.coerce) {389entry:390  %0 = bitcast float %a.coerce to i32391  %tmp.0.extract.trunc = trunc i32 %0 to i16392  %1 = bitcast i16 %tmp.0.extract.trunc to half393  %2 = bitcast float %b.coerce to i32394  %tmp1.0.extract.trunc = trunc i32 %2 to i16395  %3 = bitcast i16 %tmp1.0.extract.trunc to half396  %4 = bitcast float %c.coerce to i32397  %tmp2.0.extract.trunc = trunc i32 %4 to i16398  %5 = bitcast i16 %tmp2.0.extract.trunc to half399  %mul = fmul half %1, %3400  %add = fadd half %mul, %5401  %6 = bitcast half %add to i16402  %tmp4.0.insert.ext = zext i16 %6 to i32403  %7 = bitcast i32 %tmp4.0.insert.ext to float404  ret float %7405 406; CHECK-LABEL:                      VFMA:407; CHECK-HARDFP-FULLFP16-FAST:       vfma.f16  s2, s0, s1408; CHECK-HARDFP-FULLFP16-FAST-NEXT:  vmov.f32  s0, s2409}410 411; 14. VFMS412define float @VFMS(float %a.coerce, float %b.coerce, float %c.coerce) {413entry:414  %0 = bitcast float %a.coerce to i32415  %tmp.0.extract.trunc = trunc i32 %0 to i16416  %1 = bitcast i16 %tmp.0.extract.trunc to half417  %2 = bitcast float %b.coerce to i32418  %tmp1.0.extract.trunc = trunc i32 %2 to i16419  %3 = bitcast i16 %tmp1.0.extract.trunc to half420  %4 = bitcast float %c.coerce to i32421  %tmp2.0.extract.trunc = trunc i32 %4 to i16422  %5 = bitcast i16 %tmp2.0.extract.trunc to half423  %mul = fmul half %1, %3424  %sub = fsub half %5, %mul425  %6 = bitcast half %sub to i16426  %tmp4.0.insert.ext = zext i16 %6 to i32427  %7 = bitcast i32 %tmp4.0.insert.ext to float428  ret float %7429 430; CHECK-LABEL:                      VFMS:431; CHECK-HARDFP-FULLFP16-FAST:       vfms.f16  s2, s0, s1432; CHECK-HARDFP-FULLFP16-FAST-NEXT:  vmov.f32  s0, s2433}434 435; 15. VFNMA436define float @VFNMA(float %a.coerce, float %b.coerce, float %c.coerce) {437entry:438  %0 = bitcast float %a.coerce to i32439  %tmp.0.extract.trunc = trunc i32 %0 to i16440  %1 = bitcast i16 %tmp.0.extract.trunc to half441  %2 = bitcast float %b.coerce to i32442  %tmp1.0.extract.trunc = trunc i32 %2 to i16443  %3 = bitcast i16 %tmp1.0.extract.trunc to half444  %4 = bitcast float %c.coerce to i32445  %tmp2.0.extract.trunc = trunc i32 %4 to i16446  %5 = bitcast i16 %tmp2.0.extract.trunc to half447  %mul = fmul half %1, %3448  %sub = fsub half -0.0, %mul449  %sub2 = fsub half %sub, %5450  %6 = bitcast half %sub2 to i16451  %tmp4.0.insert.ext = zext i16 %6 to i32452  %7 = bitcast i32 %tmp4.0.insert.ext to float453  ret float %7454 455; CHECK-LABEL:                      VFNMA:456; CHECK-HARDFP-FULLFP16-FAST:       vfnma.f16  s2, s0, s1457; CHECK-HARDFP-FULLFP16-FAST-NEXT:  vmov.f32  s0, s2458}459 460; 16. VFNMS461define float @VFNMS(float %a.coerce, float %b.coerce, float %c.coerce) {462entry:463  %0 = bitcast float %a.coerce to i32464  %tmp.0.extract.trunc = trunc i32 %0 to i16465  %1 = bitcast i16 %tmp.0.extract.trunc to half466  %2 = bitcast float %b.coerce to i32467  %tmp1.0.extract.trunc = trunc i32 %2 to i16468  %3 = bitcast i16 %tmp1.0.extract.trunc to half469  %4 = bitcast float %c.coerce to i32470  %tmp2.0.extract.trunc = trunc i32 %4 to i16471  %5 = bitcast i16 %tmp2.0.extract.trunc to half472  %mul = fmul half %1, %3473  %sub2 = fsub half %mul, %5474  %6 = bitcast half %sub2 to i16475  %tmp4.0.insert.ext = zext i16 %6 to i32476  %7 = bitcast i32 %tmp4.0.insert.ext to float477  ret float %7478 479; CHECK-LABEL:                      VFNMS:480; CHECK-HARDFP-FULLFP16-FAST:       vfnms.f16  s2, s0, s1481; CHECK-HARDFP-FULLFP16-FAST-NEXT:  vmov.f32  s0, s2482}483 484; 17. VMAXNM485; 18. VMINNM486; Tested in fp16-vminmaxnm.ll and fp16-vminmaxnm-safe.ll487 488; 19. VMLA489define float @VMLA(float %a.coerce, float %b.coerce, float %c.coerce) {490entry:491  %0 = bitcast float %a.coerce to i32492  %tmp.0.extract.trunc = trunc i32 %0 to i16493  %1 = bitcast i16 %tmp.0.extract.trunc to half494  %2 = bitcast float %b.coerce to i32495  %tmp1.0.extract.trunc = trunc i32 %2 to i16496  %3 = bitcast i16 %tmp1.0.extract.trunc to half497  %4 = bitcast float %c.coerce to i32498  %tmp2.0.extract.trunc = trunc i32 %4 to i16499  %5 = bitcast i16 %tmp2.0.extract.trunc to half500  %mul = fmul half %1, %3501  %add = fadd half %5, %mul502  %6 = bitcast half %add to i16503  %tmp4.0.insert.ext = zext i16 %6 to i32504  %7 = bitcast i32 %tmp4.0.insert.ext to float505  ret float %7506 507; CHECK-LABEL:                 VMLA:508; CHECK-HARDFP-FULLFP16:       vmla.f16  s2, s0, s1509; CHECK-HARDFP-FULLFP16-NEXT:  vmov.f32  s0, s2510}511 512; 20. VMLS513define float @VMLS(float %a.coerce, float %b.coerce, float %c.coerce) {514entry:515  %0 = bitcast float %a.coerce to i32516  %tmp.0.extract.trunc = trunc i32 %0 to i16517  %1 = bitcast i16 %tmp.0.extract.trunc to half518  %2 = bitcast float %b.coerce to i32519  %tmp1.0.extract.trunc = trunc i32 %2 to i16520  %3 = bitcast i16 %tmp1.0.extract.trunc to half521  %4 = bitcast float %c.coerce to i32522  %tmp2.0.extract.trunc = trunc i32 %4 to i16523  %5 = bitcast i16 %tmp2.0.extract.trunc to half524  %mul = fmul half %1, %3525  %add = fsub half %5, %mul526  %6 = bitcast half %add to i16527  %tmp4.0.insert.ext = zext i16 %6 to i32528  %7 = bitcast i32 %tmp4.0.insert.ext to float529  ret float %7530 531; CHECK-LABEL:                 VMLS:532; CHECK-HARDFP-FULLFP16:       vmls.f16  s2, s0, s1533; CHECK-HARDFP-FULLFP16-NEXT:  vmov.f32  s0, s2534}535 536; TODO: fix immediates.537; 21. VMOV (between general-purpose register and half-precision register)538 539; 22. VMOV (immediate)540define i32 @movi(i32 %a.coerce) {541entry:542  %tmp.0.extract.trunc = trunc i32 %a.coerce to i16543  %0 = bitcast i16 %tmp.0.extract.trunc to half544  %add = fadd half %0, 0xHC000545  %1 = bitcast half %add to i16546  %tmp2.0.insert.ext = zext i16 %1 to i32547  ret i32 %tmp2.0.insert.ext548 549; CHECK-LABEL:            movi:550; CHECK-HARDFP-FULLFP16:  vmov.f16  s0, #-2.000000e+00551}552 553; 23. VMUL554define float @Mul(float %a.coerce, float %b.coerce) {555entry:556  %0 = bitcast float %a.coerce to i32557  %tmp.0.extract.trunc = trunc i32 %0 to i16558  %1 = bitcast i16 %tmp.0.extract.trunc to half559  %2 = bitcast float %b.coerce to i32560  %tmp1.0.extract.trunc = trunc i32 %2 to i16561  %3 = bitcast i16 %tmp1.0.extract.trunc to half562  %add = fmul half %1, %3563  %4 = bitcast half %add to i16564  %tmp4.0.insert.ext = zext i16 %4 to i32565  %5 = bitcast i32 %tmp4.0.insert.ext to float566  ret float %5567 568; CHECK-LABEL:  Mul:569 570; CHECK-SOFT:  bl  __aeabi_h2f571; CHECK-SOFT:  bl  __aeabi_h2f572; CHECK-SOFT:  bl  __aeabi_fmul573; CHECK-SOFT:  bl  __aeabi_f2h574 575; CHECK-SOFTFP-VFP3:  bl  __aeabi_h2f576; CHECK-SOFTFP-VFP3:  bl  __aeabi_h2f577; CHECK-SOFTFP-VFP3:  vmul.f32578; CHECK-SOFTFP-VFP3:  bl  __aeabi_f2h579 580; CHECK-SOFTFP-FP16-DAG:  vmov          [[S0:s[0-9]]], r0581; CHECK-SOFTFP-FP16-DAG:  vmov          [[S2:s[0-9]]], r1582; CHECK-SOFTFP-FP16-DAG:  vcvtb.f32.f16 [[S0]], [[S0]]583; CHECK-SOFTFP-FP16-DAG:  vcvtb.f32.f16 [[S2]], [[S2]]584; CHECK-SOFTFP-FP16:  vmul.f32      [[S0]], [[S0]], [[S2]]585; CHECK-SOFTFP-FP16:  vcvtb.f16.f32 [[S0]], [[S0]]586; CHECK-SOFTFP-FP16:  vmov  r0, s0587 588; CHECK-SOFTFP-FULLFP16:       vmov.f16  [[S0:s[0-9]]], r1589; CHECK-SOFTFP-FULLFP16:       vmov.f16  [[S2:s[0-9]]], r0590; CHECK-SOFTFP-FULLFP16:       vmul.f16  [[S0]], [[S2]], [[S0]]591; CHECK-SOFTFP-FULLFP16-NEXT:  vmov.f16  r0, s0592 593; CHECK-HARDFP-VFP3:  vmov r594; CHECK-HARDFP-VFP3:  vmov.f32 s595; CHECK-HARDFP-VFP3:  bl  __aeabi_h2f596; CHECK-HARDFP-VFP3:  bl  __aeabi_h2f597; CHECK-HARDFP-VFP3:  vmul.f32598; CHECK-HARDFP-VFP3:  bl  __aeabi_f2h599; CHECK-HARDFP-VFP3:  vmov  s0, r0600 601; CHECK-HARDFP-FP16:  vcvtb.f32.f16 [[S2:s[0-9]]], s1602; CHECK-HARDFP-FP16:  vcvtb.f32.f16 [[S0:s[0-9]]], s0603; CHECK-HARDFP-FP16:  vmul.f32  [[S0]], [[S0]], [[S2]]604; CHECK-HARDFP-FP16:  vcvtb.f16.f32 [[S0]], [[S0]]605 606; CHECK-HARDFP-FULLFP16:       vmul.f16  s0, s0, s1607}608 609; 24. VNEG610define float @Neg(float %a.coerce) {611entry:612  %0 = bitcast float %a.coerce to i32613  %tmp.0.extract.trunc = trunc i32 %0 to i16614  %1 = bitcast i16 %tmp.0.extract.trunc to half615  %2 = fsub half -0.000000e+00, %1616  %3 = bitcast half %2 to i16617  %tmp4.0.insert.ext = zext i16 %3 to i32618  %4 = bitcast i32 %tmp4.0.insert.ext to float619  ret float %4620 621; CHECK-LABEL:                 Neg:622; CHECK-HARDFP-FULLFP16:       vneg.f16  s0, s0623}624 625; 25. VNMLA626define float @VNMLA(float %a.coerce, float %b.coerce, float %c.coerce) {627entry:628  %0 = bitcast float %a.coerce to i32629  %tmp.0.extract.trunc = trunc i32 %0 to i16630  %1 = bitcast i16 %tmp.0.extract.trunc to half631  %2 = bitcast float %b.coerce to i32632  %tmp1.0.extract.trunc = trunc i32 %2 to i16633  %3 = bitcast i16 %tmp1.0.extract.trunc to half634  %4 = bitcast float %c.coerce to i32635  %tmp2.0.extract.trunc = trunc i32 %4 to i16636  %5 = bitcast i16 %tmp2.0.extract.trunc to half637  %add = fmul half %1, %3638  %add2 = fsub half -0.000000e+00, %add639  %add3 = fsub half %add2, %5640  %6 = bitcast half %add3 to i16641  %tmp4.0.insert.ext = zext i16 %6 to i32642  %7 = bitcast i32 %tmp4.0.insert.ext to float643  ret float %7644 645; CHECK-LABEL:            VNMLA:646; CHECK-HARDFP-FULLFP16:  vnmla.f16 s2, s0, s1647; CHECK-HARDFP-FULLFP16:  vmov.f32  s0, s2648}649 650; 26. VNMLS651define float @VNMLS(float %a.coerce, float %b.coerce, float %c.coerce) {652entry:653  %0 = bitcast float %a.coerce to i32654  %tmp.0.extract.trunc = trunc i32 %0 to i16655  %1 = bitcast i16 %tmp.0.extract.trunc to half656  %2 = bitcast float %b.coerce to i32657  %tmp1.0.extract.trunc = trunc i32 %2 to i16658  %3 = bitcast i16 %tmp1.0.extract.trunc to half659  %4 = bitcast float %c.coerce to i32660  %tmp2.0.extract.trunc = trunc i32 %4 to i16661  %5 = bitcast i16 %tmp2.0.extract.trunc to half662  %add = fmul half %1, %3663  %add2 = fsub half %add, %5664  %6 = bitcast half %add2 to i16665  %tmp4.0.insert.ext = zext i16 %6 to i32666  %7 = bitcast i32 %tmp4.0.insert.ext to float667  ret float %7668 669; CHECK-LABEL:            VNMLS:670; CHECK-HARDFP-FULLFP16:  vnmls.f16 s2, s0, s1671; CHECK-HARDFP-FULLFP16:  vmov.f32  s0, s2672}673 674; 27. VNMUL675define float @NMul(float %a.coerce, float %b.coerce) {676entry:677  %0 = bitcast float %a.coerce to i32678  %tmp.0.extract.trunc = trunc i32 %0 to i16679  %1 = bitcast i16 %tmp.0.extract.trunc to half680  %2 = bitcast float %b.coerce to i32681  %tmp1.0.extract.trunc = trunc i32 %2 to i16682  %3 = bitcast i16 %tmp1.0.extract.trunc to half683  %add = fmul half %1, %3684  %add2 = fsub half -0.0, %add685  %4 = bitcast half %add2 to i16686  %tmp4.0.insert.ext = zext i16 %4 to i32687  %5 = bitcast i32 %tmp4.0.insert.ext to float688  ret float %5689 690; CHECK-LABEL:                 NMul:691; CHECK-HARDFP-FULLFP16:       vnmul.f16  s0, s0, s1692}693 694; 35. VSELEQ695define half @select_cc1(ptr %a0)  {696  %1 = load half, ptr %a0697  %2 = fcmp nsz oeq half %1, 0xH0001698  %3 = select i1 %2, half 0xHC000, half 0xH0002699  ret half %3700 701; CHECK-LABEL:                 select_cc1:702 703; CHECK-HARDFP-FULLFP16:  vcmp.f16704; CHECK-HARDFP-FULLFP16:  vmrs APSR_nzcv, fpscr705; CHECK-HARDFP-FULLFP16:  vseleq.f16 s0,706 707; CHECK-SOFTFP-FP16-A32:       vcmp.f32708; CHECK-SOFTFP-FP16-A32-NEXT:  vmrs APSR_nzcv, fpscr709; CHECK-SOFTFP-FP16-A32-NEXT:  movne r0,710 711; CHECK-SOFTFP-FP16-T32:       vcmp.f32712; CHECK-SOFTFP-FP16-T32-NEXT:  vmrs APSR_nzcv, fpscr713; CHECK-SOFTFP-FP16-T32-NEXT:  itt eq714; CHECK-SOFTFP-FP16-T32-NEXT:  movweq r0,715; CHECK-SOFTFP-FP16-T32-NEXT:  movteq r0,716}717 718; FIXME: more tests need to be added for VSELGE and VSELGT.719; That is, more combinations of immediate operands that can or can't720; be encoded as an FP16 immediate need to be added here.721;722; 36. VSELGE723define half @select_cc_ge1(ptr %a0)  {724  %1 = load half, ptr %a0725  %2 = fcmp nsz oge half %1, 0xH0001726  %3 = select i1 %2, half 0xHC000, half 0xH0002727  ret half %3728 729; CHECK-LABEL:                 select_cc_ge1:730 731; CHECK-HARDFP-FULLFP16:  vcmp.f16732; CHECK-HARDFP-FULLFP16:  vmrs APSR_nzcv, fpscr733; CHECK-HARDFP-FULLFP16:  vselge.f16 s0,734 735; CHECK-SOFTFP-FP16-A32:       vcmp.f32736; CHECK-SOFTFP-FP16-A32-NEXT:  vmrs APSR_nzcv, fpscr737; CHECK-SOFTFP-FP16-A32-NEXT:  movlt r0,738 739; CHECK-SOFTFP-FP16-T32:       vcmp.f32740; CHECK-SOFTFP-FP16-T32-NEXT:  vmrs APSR_nzcv, fpscr741; CHECK-SOFTFP-FP16-T32-NEXT:  itt ge742; CHECK-SOFTFP-FP16-T32-NEXT:  movwge r0,743; CHECK-SOFTFP-FP16-T32-NEXT:  movtge r0,744}745 746define half @select_cc_ge2(ptr %a0)  {747  %1 = load half, ptr %a0748  %2 = fcmp nsz ole half %1, 0xH0001749  %3 = select i1 %2, half 0xHC000, half 0xH0002750  ret half %3751 752; CHECK-LABEL:                 select_cc_ge2:753 754; CHECK-HARDFP-FULLFP16:  vcmp.f16755; CHECK-HARDFP-FULLFP16:  vmrs APSR_nzcv, fpscr756; CHECK-HARDFP-FULLFP16:  vselge.f16 s0,757 758; CHECK-SOFTFP-FP16-A32:       vcmp.f32759; CHECK-SOFTFP-FP16-A32-NEXT:  vmrs APSR_nzcv, fpscr760; CHECK-SOFTFP-FP16-A32-NEXT:  movhi r0,761 762; CHECK-SOFTFP-FP16-T32:       vcmp.f32763; CHECK-SOFTFP-FP16-T32-NEXT:  vmrs APSR_nzcv, fpscr764; CHECK-SOFTFP-FP16-T32-NEXT:  itt ls765; CHECK-SOFTFP-FP16-T32-NEXT:  movwls r0,766; CHECK-SOFTFP-FP16-T32-NEXT:  movtls r0,767}768 769define half @select_cc_ge3(ptr %a0)  {770  %1 = load half, ptr %a0771  %2 = fcmp nsz ugt half %1, 0xH0001772  %3 = select i1 %2, half 0xHC000, half 0xH0002773  ret half %3774 775; CHECK-LABEL:                 select_cc_ge3:776 777; CHECK-HARDFP-FULLFP16:  vcmp.f16778; CHECK-HARDFP-FULLFP16:  vmrs APSR_nzcv, fpscr779; CHECK-HARDFP-FULLFP16:  vselge.f16 s0,780 781; CHECK-SOFTFP-FP16-A32:       vcmp.f32782; CHECK-SOFTFP-FP16-A32-NEXT:  vmrs APSR_nzcv, fpscr783; CHECK-SOFTFP-FP16-A32-NEXT:  movls r0,784 785; CHECK-SOFTFP-FP16-T32:       vcmp.f32786; CHECK-SOFTFP-FP16-T32-NEXT:  vmrs APSR_nzcv, fpscr787; CHECK-SOFTFP-FP16-T32-NEXT:  itt hi788; CHECK-SOFTFP-FP16-T32-NEXT:  movwhi r0,789; CHECK-SOFTFP-FP16-T32-NEXT:  movthi r0,790}791 792define half @select_cc_ge4(ptr %a0)  {793  %1 = load half, ptr %a0794  %2 = fcmp nsz ult half %1, 0xH0001795  %3 = select i1 %2, half 0xHC000, half 0xH0002796  ret half %3797 798; CHECK-LABEL:                 select_cc_ge4:799 800; CHECK-HARDFP-FULLFP16:  vcmp.f16801; CHECK-HARDFP-FULLFP16:  vmrs APSR_nzcv, fpscr802; CHECK-HARDFP-FULLFP16:  vselge.f16 s0, s{{.}}, s{{.}}803 804; CHECK-SOFTFP-FP16-A32:       vcmp.f32805; CHECK-SOFTFP-FP16-A32-NEXT:  vmrs APSR_nzcv, fpscr806; CHECK-SOFTFP-FP16-A32-NEXT:  movge r0,807 808; CHECK-SOFTFP-FP16-T32:       vcmp.f32809; CHECK-SOFTFP-FP16-T32-NEXT:  vmrs APSR_nzcv, fpscr810; CHECK-SOFTFP-FP16-T32-NEXT:  itt lt811; CHECK-SOFTFP-FP16-T32-NEXT:  movwlt r0,812; CHECK-SOFTFP-FP16-T32-NEXT:  movtlt r0,813}814 815; 37. VSELGT816define half @select_cc_gt1(ptr %a0)  {817  %1 = load half, ptr %a0818  %2 = fcmp nsz ogt half %1, 0xH0001819  %3 = select i1 %2, half 0xHC000, half 0xH0002820  ret half %3821 822; CHECK-LABEL:                 select_cc_gt1:823 824; CHECK-HARDFP-FULLFP16:  vcmp.f16825; CHECK-HARDFP-FULLFP16:  vmrs APSR_nzcv, fpscr826; CHECK-HARDFP-FULLFP16:  vselgt.f16  s0, s{{.}}, s{{.}}827 828; CHECK-SOFTFP-FP16-A32:       vcmp.f32829; CHECK-SOFTFP-FP16-A32-NEXT:  vmrs APSR_nzcv, fpscr830; CHECK-SOFTFP-FP16-A32-NEXT:  movle r0,831 832; CHECK-SOFTFP-FP16-T32:       vcmp.f32833; CHECK-SOFTFP-FP16-T32-NEXT:  vmrs APSR_nzcv, fpscr834; CHECK-SOFTFP-FP16-T32-NEXT:  itt gt835; CHECK-SOFTFP-FP16-T32-NEXT:  movwgt r0,836; CHECK-SOFTFP-FP16-T32-NEXT:  movtgt r0,837}838 839define half @select_cc_gt2(ptr %a0)  {840  %1 = load half, ptr %a0841  %2 = fcmp nsz uge half %1, 0xH0001842  %3 = select i1 %2, half 0xHC000, half 0xH0002843  ret half %3844 845; CHECK-LABEL:                 select_cc_gt2:846 847; CHECK-HARDFP-FULLFP16:  vcmp.f16848; CHECK-HARDFP-FULLFP16:  vmrs  APSR_nzcv, fpscr849; CHECK-HARDFP-FULLFP16:  vselgt.f16  s0, s{{.}}, s{{.}}850 851; CHECK-SOFTFP-FP16-A32:       vcmp.f32852; CHECK-SOFTFP-FP16-A32-NEXT:  vmrs APSR_nzcv, fpscr853; CHECK-SOFTFP-FP16-A32-NEXT:  movmi r0,854 855; CHECK-SOFTFP-FP16-T32:       vcmp.f32856; CHECK-SOFTFP-FP16-T32-NEXT:  vmrs APSR_nzcv, fpscr857; CHECK-SOFTFP-FP16-T32-NEXT:  itt pl858; CHECK-SOFTFP-FP16-T32-NEXT:  movwpl r0,859; CHECK-SOFTFP-FP16-T32-NEXT:  movtpl r0,860}861 862define half @select_cc_gt3(ptr %a0)  {863  %1 = load half, ptr %a0864  %2 = fcmp nsz ule half %1, 0xH0001865  %3 = select i1 %2, half 0xHC000, half 0xH0002866  ret half %3867 868; CHECK-LABEL:                 select_cc_gt3:869 870; CHECK-HARDFP-FULLFP16:  vcmp.f16871; CHECK-HARDFP-FULLFP16:  vmrs  APSR_nzcv, fpscr872; CHECK-HARDFP-FULLFP16:  vselgt.f16  s0, s{{.}}, s{{.}}873 874; CHECK-SOFTFP-FP16-A32:       vcmp.f32875; CHECK-SOFTFP-FP16-A32-NEXT:  vmrs APSR_nzcv, fpscr876; CHECK-SOFTFP-FP16-A32-NEXT:  movgt r0,877 878; CHECK-SOFTFP-FP16-T32:       vcmp.f32879; CHECK-SOFTFP-FP16-T32-NEXT:  vmrs APSR_nzcv, fpscr880; CHECK-SOFTFP-FP16-T32-NEXT:  itt le881; CHECK-SOFTFP-FP16-T32-NEXT:  movwle r0,882; CHECK-SOFTFP-FP16-T32-NEXT:  movtle r0,883}884 885define half @select_cc_gt4(ptr %a0)  {886  %1 = load half, ptr %a0887  %2 = fcmp nsz olt half %1, 0xH0001888  %3 = select i1 %2, half 0xHC000, half 0xH0002889  ret half %3890 891; CHECK-LABEL:                 select_cc_gt4:892 893; CHECK-HARDFP-FULLFP16:  vcmp.f16894; CHECK-HARDFP-FULLFP16:  vmrs  APSR_nzcv, fpscr895; CHECK-HARDFP-FULLFP16:  vselgt.f16  s0, s{{.}}, s{{.}}896 897; CHECK-SOFTFP-FP16-A32:       vcmp.f32898; CHECK-SOFTFP-FP16-A32-NEXT:  vmrs APSR_nzcv, fpscr899; CHECK-SOFTFP-FP16-A32-NEXT:  movpl r0,900 901; CHECK-SOFTFP-FP16-T32:       vcmp.f32902; CHECK-SOFTFP-FP16-T32-NEXT:  vmrs APSR_nzcv, fpscr903; CHECK-SOFTFP-FP16-T32-NEXT:  itt mi904; CHECK-SOFTFP-FP16-T32-NEXT:  movwmi r0,905; CHECK-SOFTFP-FP16-T32-NEXT:  movtmi r0,906}907 908; 38. VSELVS909define float @select_cc4(float %a.coerce) {910entry:911  %0 = bitcast float %a.coerce to i32912  %tmp.0.extract.trunc = trunc i32 %0 to i16913  %1 = bitcast i16 %tmp.0.extract.trunc to half914 915  %2 = fcmp nsz ueq half %1, 0xH0001916  %3 = select i1 %2, half 0xHC000, half 0xH0002917 918  %4 = bitcast half %3 to i16919  %tmp4.0.insert.ext = zext i16 %4 to i32920  %5 = bitcast i32 %tmp4.0.insert.ext to float921  ret float %5922 923; CHECK-LABEL:                 select_cc4:924 925; CHECK-HARDFP-FULLFP16:       vldr.16	[[S2:s[0-9]]], .LCPI{{.*}}926; CHECK-HARDFP-FULLFP16:       vcmp.f16	s0, [[S2]]927; CHECK-HARDFP-FULLFP16:       vldr.16	[[S4:s[0-9]]], .LCPI{{.*}}928; CHECK-HARDFP-FULLFP16:       vmrs	APSR_nzcv, fpscr929; CHECK-HARDFP-FULLFP16:       vmov.f16 [[S6:s[0-9]]], #-2.000000e+00930; CHECK-HARDFP-FULLFP16-NEXT:  vseleq.f16	[[S0:s[0-9]]], [[S6]], [[S4]]931; CHECK-HARDFP-FULLFP16-NEXT:  vselvs.f16	s0, [[S6]], [[S0]]932 933; CHECK-SOFTFP-FP16-A32:       vmov	[[S6:s[0-9]]], r0934; CHECK-SOFTFP-FP16-A32:       vldr	s0, .LCP{{.*}}935; CHECK-SOFTFP-FP16-A32:       vcvtb.f32.f16	[[S6]], [[S6]]936; CHECK-SOFTFP-FP16-A32:       ldr      r1, .LCP{{.*}}937; CHECK-SOFTFP-FP16-A32:       vcmp.f32	[[S6]], s0938; CHECK-SOFTFP-FP16-A32:       vmrs	APSR_nzcv, fpscr939; CHECK-SOFTFP-FP16-A32:       mov      r0, r1940; CHECK-SOFTFP-FP16-A32-NEXT:  movne    r0, #2941; CHECK-SOFTFP-FP16-A32-NEXT:  movvs    r0, r1942 943; CHECK-SOFTFP-FP16-T32:       vmov	[[S6:s[0-9]]], r0944; CHECK-SOFTFP-FP16-T32:       vldr	s0, .LCP{{.*}}945; CHECK-SOFTFP-FP16-T32:       vcvtb.f32.f16	[[S6]], [[S6]]946; CHECK-SOFTFP-FP16-T32:       vcmp.f32	[[S6]], s0947; CHECK-SOFTFP-FP16-T32:       vmrs	APSR_nzcv, fpscr948; CHECK-SOFTFP-FP16-T32:       itt      eq949; CHECK-SOFTFP-FP16-T32-NEXT:  movweq   r1,950; CHECK-SOFTFP-FP16-T32-NEXT:  movteq   r1,951; CHECK-SOFTFP-FP16-T32-NEXT:  itt      vs952; CHECK-SOFTFP-FP16-T32-NEXT:  movwvs   r1,953; CHECK-SOFTFP-FP16-T32-NEXT:  movtvs   r1,954; CHECK-SOFTFP-FP16-T32-NEXT:  uxth     r0, r1955}956 957; 40. VSUB958define float @Sub(float %a.coerce, float %b.coerce) {959entry:960  %0 = bitcast float %a.coerce to i32961  %tmp.0.extract.trunc = trunc i32 %0 to i16962  %1 = bitcast i16 %tmp.0.extract.trunc to half963  %2 = bitcast float %b.coerce to i32964  %tmp1.0.extract.trunc = trunc i32 %2 to i16965  %3 = bitcast i16 %tmp1.0.extract.trunc to half966  %add = fsub half %1, %3967  %4 = bitcast half %add to i16968  %tmp4.0.insert.ext = zext i16 %4 to i32969  %5 = bitcast i32 %tmp4.0.insert.ext to float970  ret float %5971 972; CHECK-LABEL:  Sub:973 974; CHECK-SOFT:  bl  __aeabi_h2f975; CHECK-SOFT:  bl  __aeabi_h2f976; CHECK-SOFT:  bl  __aeabi_fsub977; CHECK-SOFT:  bl  __aeabi_f2h978 979; CHECK-SOFTFP-VFP3:  bl  __aeabi_h2f980; CHECK-SOFTFP-VFP3:  bl  __aeabi_h2f981; CHECK-SOFTFP-VFP3:  vsub.f32982; CHECK-SOFTFP-VFP3:  bl  __aeabi_f2h983 984; CHECK-SOFTFP-FP16-DAG:  vmov          [[S0:s[0-9]]], r0985; CHECK-SOFTFP-FP16-DAG:  vmov          [[S2:s[0-9]]], r1986; CHECK-SOFTFP-FP16-DAG:  vcvtb.f32.f16 [[S0]], [[S0]]987; CHECK-SOFTFP-FP16-DAG:  vcvtb.f32.f16 [[S2]], [[S2]]988; CHECK-SOFTFP-FP16:  vsub.f32      [[S0]], [[S0]], [[S2]]989; CHECK-SOFTFP-FP16:  vcvtb.f16.f32 [[S0]], [[S0]]990; CHECK-SOFTFP-FP16:  vmov  r0, s0991 992; CHECK-SOFTFP-FULLFP16:       vmov.f16  [[S0:s[0-9]]], r1993; CHECK-SOFTFP-FULLFP16:       vmov.f16  [[S2:s[0-9]]], r0994; CHECK-SOFTFP-FULLFP16:       vsub.f16  [[S0]], [[S2]], [[S0]]995; CHECK-SOFTFP-FULLFP16-NEXT:  vmov.f16  r0, s0996 997; CHECK-HARDFP-VFP3:  vmov r998; CHECK-HARDFP-VFP3:  vmov.f32 s999; CHECK-HARDFP-VFP3:  bl  __aeabi_h2f1000; CHECK-HARDFP-VFP3:  bl  __aeabi_h2f1001; CHECK-HARDFP-VFP3:  vsub.f321002; CHECK-HARDFP-VFP3:  bl  __aeabi_f2h1003; CHECK-HARDFP-VFP3:  vmov  s0, r01004 1005; CHECK-HARDFP-FP16:  vcvtb.f32.f16 [[S2:s[0-9]]], s11006; CHECK-HARDFP-FP16:  vcvtb.f32.f16 [[S0:s[0-9]]], s01007; CHECK-HARDFP-FP16:  vsub.f32  [[S0]], [[S0]], [[S2]]1008; CHECK-HARDFP-FP16:  vcvtb.f16.f32 [[S0]], [[S0]]1009 1010; CHECK-HARDFP-FULLFP16:       vsub.f16  s0, s0, s11011}1012 1013; Check for VSTRH with a FCONSTH, this checks that addressing mode1014; AddrMode5FP16 is supported.1015define i32 @ThumbAddrMode5FP16(i32 %A.coerce) {1016entry:1017  %S = alloca half, align 21018  %tmp.0.extract.trunc = trunc i32 %A.coerce to i161019  %0 = bitcast i16 %tmp.0.extract.trunc to half1020  store volatile half 0xH3C00, ptr %S, align 21021  %S.0.S.0. = load volatile half, ptr %S, align 21022  %add = fadd half %S.0.S.0., %01023  %1 = bitcast half %add to i161024  %tmp2.0.insert.ext = zext i16 %1 to i321025  ret i32 %tmp2.0.insert.ext1026 1027; CHECK-LABEL:            ThumbAddrMode5FP161028 1029; CHECK-SOFTFP-FULLFP16:  vmov.f16    [[S0:s[0-9]]], #1.000000e+001030; CHECK-SOFTFP-FULLFP16:  vstr.16     [[S0]], [sp, #{{.}}]1031; CHECK-SOFTFP-FULLFP16:  vmov.f16    [[S0_2:s[0-9]]], r01032; CHECK-SOFTFP-FULLFP16:  vldr.16     [[S2:s[0-9]]], [sp, #{{.}}]1033; CHECK-SOFTFP-FULLFP16:  vadd.f16    s{{.}}, [[S2]], [[S0_2]]1034}1035 1036; Test function calls to check store/load reg to/from stack1037define i32 @fn1() {1038entry:1039  %coerce = alloca half, align 21040  %tmp2 = alloca i32, align 41041  store half 0xH7C00, ptr %coerce, align 21042  %0 = load i32, ptr %tmp2, align 41043  %call = call i32 @fn2(i32 %0)1044  store half 0xH7C00, ptr %coerce, align 21045  %1 = load i32, ptr %tmp2, align 41046  %call3 = call i32 @fn3(i32 %1)1047  ret i32 %call31048 1049; CHECK-SPILL-RELOAD-LABEL: fn1:1050; CHECK-SPILL-RELOAD:       vstr.16 s0, [sp, #{{.}}]  @ 2-byte Spill1051; CHECK-SPILL-RELOAD:  bl  fn21052; CHECK-SPILL-RELOAD-NEXT:  vldr.16 s0, [sp, #{{.}}]  @ 2-byte Reload1053}1054 1055declare dso_local i32 @fn2(...)1056declare dso_local i32 @fn3(...)1057