brintos

brintos / llvm-project-archived public Read only

0
0
Text · 7.2 KiB · 191c775 Raw
312 lines · plain
1; RUN: llc < %s -mtriple=thumbv7-none-eabi   -mcpu=cortex-m3 | FileCheck %s -check-prefix=CHECK -check-prefix=NONE -check-prefix=NOREGS2; RUN: llc < %s -mtriple=thumbv7-none-eabihf -mcpu=cortex-m4 | FileCheck %s -check-prefix=CHECK -check-prefix=HARD -check-prefix=SP -check-prefix=VFP4-ALL3; RUN: llc < %s -mtriple=thumbv7-none-eabihf -mcpu=cortex-m7 | FileCheck %s -check-prefix=CHECK -check-prefix=HARD -check-prefix=DP -check-prefix=FP-ARMv84; RUN: llc < %s -mtriple=thumbv7-none-eabihf -mcpu=cortex-a8 | FileCheck %s -check-prefix=CHECK -check-prefix=HARD -check-prefix=DP -check-prefix=VFP4-ALL -check-prefix=VFP4-DP5; RUN: llc < %s -mtriple=thumbv8.1m.main-none-eabihf -mattr=+mve | FileCheck %s -check-prefix=CHECK -check-prefix=NONE -check-prefix=ONLYREGS6 7define float @add_f(float %a, float %b) {8entry:9; CHECK-LABEL: add_f:10; NONE: {{b|bl}} __aeabi_fadd11; HARD: vadd.f32  s0, s0, s112  %0 = fadd float %a, %b13  ret float %014}15 16define double @add_d(double %a, double %b) {17entry:18; CHECK-LABEL: add_d:19; NONE: {{b|bl}} __aeabi_dadd20; SP: {{b|bl}} __aeabi_dadd21; DP: vadd.f64  d0, d0, d122  %0 = fadd double %a, %b23  ret double %024}25 26define float @sub_f(float %a, float %b) {27entry:28; CHECK-LABEL: sub_f:29; NONE: {{b|bl}} __aeabi_fsub30; HARD: vsub.f32  s31  %0 = fsub float %a, %b32  ret float %033}34 35define double @sub_d(double %a, double %b) {36entry:37; CHECK-LABEL: sub_d:38; NONE: {{b|bl}} __aeabi_dsub39; SP: {{b|bl}} __aeabi_dsub40; DP: vsub.f64  d0, d0, d141  %0 = fsub double %a, %b42  ret double %043}44 45define float @mul_f(float %a, float %b) {46entry:47; CHECK-LABEL: mul_f:48; NONE: {{b|bl}} __aeabi_fmul49; HARD: vmul.f32  s50  %0 = fmul float %a, %b51  ret float %052}53 54define double @mul_d(double %a, double %b) {55entry:56; CHECK-LABEL: mul_d:57; NONE: {{b|bl}} __aeabi_dmul58; SP: {{b|bl}} __aeabi_dmul59; DP: vmul.f64  d0, d0, d160  %0 = fmul double %a, %b61  ret double %062}63 64define float @div_f(float %a, float %b) {65entry:66; CHECK-LABEL: div_f:67; NONE: {{b|bl}} __aeabi_fdiv68; HARD: vdiv.f32  s69  %0 = fdiv float %a, %b70  ret float %071}72 73define double @div_d(double %a, double %b) {74entry:75; CHECK-LABEL: div_d:76; NONE: {{b|bl}} __aeabi_ddiv77; SP: {{b|bl}} __aeabi_ddiv78; DP: vdiv.f64  d0, d0, d179  %0 = fdiv double %a, %b80  ret double %081}82 83define float @rem_f(float %a, float %b) {84entry:85; CHECK-LABEL: rem_f:86; NONE: {{b|bl}} fmodf87; HARD: b fmodf88  %0 = frem float %a, %b89  ret float %090}91 92define double @rem_d(double %a, double %b) {93entry:94; CHECK-LABEL: rem_d:95; NONE: {{b|bl}} fmod96; HARD: b fmod97  %0 = frem double %a, %b98  ret double %099}100 101; In the ONLYREGS case (where we have integer MVE but no floating102; point), we still expect the hard float ABI, because we asked for it103; in the triple, and since the FP registers exist, it's possible to104; use them to pass arguments. So the generated code should load the105; return value into s0, not r0. Similarly for the other load and store106; tests.107define float @load_f(ptr %a) {108entry:109; CHECK-LABEL: load_f:110; NOREGS: ldr r0, [r0]111; ONLYREGS: vldr s0, [r0]112; HARD: vldr s0, [r0]113  %0 = load float, ptr %a, align 4114  ret float %0115}116 117define double @load_d(ptr %a) {118entry:119; CHECK-LABEL: load_d:120; NOREGS: ldm r0, {r0, r1}121; ONLYREGS: vldr d0, [r0]122; HARD: vldr d0, [r0]123  %0 = load double, ptr %a, align 8124  ret double %0125}126 127define void @store_f(ptr %a, float %b) {128entry:129; CHECK-LABEL: store_f:130; NOREGS: str r1, [r0]131; ONLYREGS: vstr s0, [r0]132; HARD: vstr s0, [r0]133  store float %b, ptr %a, align 4134  ret void135}136 137define void @store_d(ptr %a, double %b) {138entry:139; CHECK-LABEL: store_d:140; NOREGS: strd r2, r3, [r0]141; ONLYREGS: vstr d0, [r0]142; HARD: vstr d0, [r0]143  store double %b, ptr %a, align 8144  ret void145}146 147define double @f_to_d(float %a) {148; CHECK-LABEL: f_to_d:149; NONE: bl __aeabi_f2d150; SP: bl __aeabi_f2d151; DP: vcvt.f64.f32 d0, s0152  %1 = fpext float %a to double153  ret double %1154}155 156define float @d_to_f(double %a) {157; CHECK-LABEL: d_to_f:158; NONE: bl __aeabi_d2f159; SP: bl __aeabi_d2f160; DP: vcvt.f32.f64 s0, d0161  %1 = fptrunc double %a to float162  ret float %1163}164 165define i32 @f_to_si(float %a) {166; CHECK-LABEL: f_to_si:167; NONE: bl __aeabi_f2iz168; HARD: vcvt.s32.f32 s0, s0169; HARD: vmov r0, s0170  %1 = fptosi float %a to i32171  ret i32 %1172}173 174define i32 @d_to_si(double %a) {175; CHECK-LABEL: d_to_si:176; NONE: bl __aeabi_d2iz177; SP: vmov r0, r1, d0178; SP: bl __aeabi_d2iz179; DP: vcvt.s32.f64 s0, d0180; DP: vmov r0, s0181  %1 = fptosi double %a to i32182  ret i32 %1183}184 185define i32 @f_to_ui(float %a) {186; CHECK-LABEL: f_to_ui:187; NONE: bl __aeabi_f2uiz188; HARD: vcvt.u32.f32 s0, s0189; HARD: vmov r0, s0190  %1 = fptoui float %a to i32191  ret i32 %1192}193 194define i32 @d_to_ui(double %a) {195; CHECK-LABEL: d_to_ui:196; NONE: bl __aeabi_d2uiz197; SP: vmov r0, r1, d0198; SP: bl __aeabi_d2uiz199; DP: vcvt.u32.f64 s0, d0200; DP: vmov r0, s0201  %1 = fptoui double %a to i32202  ret i32 %1203}204 205define float @si_to_f(i32 %a) {206; CHECK-LABEL: si_to_f:207; NONE: bl __aeabi_i2f208; HARD: vcvt.f32.s32 s0, s0209  %1 = sitofp i32 %a to float210  ret float %1211}212 213define double @si_to_d(i32 %a) {214; CHECK-LABEL: si_to_d:215; NONE: bl __aeabi_i2d216; SP: bl __aeabi_i2d217; DP: vcvt.f64.s32 d0, s0218  %1 = sitofp i32 %a to double219  ret double %1220}221 222define float @ui_to_f(i32 %a) {223; CHECK-LABEL: ui_to_f:224; NONE: bl __aeabi_ui2f225; HARD: vcvt.f32.u32 s0, s0226  %1 = uitofp i32 %a to float227  ret float %1228}229 230define double @ui_to_d(i32 %a) {231; CHECK-LABEL: ui_to_d:232; NONE: bl __aeabi_ui2d233; SP: bl __aeabi_ui2d234; DP: vcvt.f64.u32 d0, s0235  %1 = uitofp i32 %a to double236  ret double %1237}238 239define float @bitcast_i_to_f(i32 %a) {240; CHECK-LABEL: bitcast_i_to_f:241; NOREGS-NOT: mov242; ONLYREGS: vmov s0, r0243; HARD: vmov s0, r0244  %1 = bitcast i32 %a to float245  ret float %1246}247 248define double @bitcast_i_to_d(i64 %a) {249; CHECK-LABEL: bitcast_i_to_d:250; NOREGS-NOT: mov251; ONLYREGS: vmov d0, r0, r1252; HARD: vmov d0, r0, r1253 %1 = bitcast i64 %a to double254  ret double %1255}256 257define i32 @bitcast_f_to_i(float %a) {258; CHECK-LABEL: bitcast_f_to_i:259; NOREGS-NOT: mov260; ONLYREGS: vmov r0, s0261; HARD: vmov r0, s0262  %1 = bitcast float %a to i32263  ret i32 %1264}265 266define i64 @bitcast_d_to_i(double %a) {267; CHECK-LABEL: bitcast_d_to_i:268; NOREGS-NOT: mov269; ONLYREGS: vmov r0, r1, d0270; HARD: vmov r0, r1, d0271  %1 = bitcast double %a to i64272  ret i64 %1273}274 275define float @select_f(float %a, float %b, i1 %c) {276; CHECK-LABEL: select_f:277; NOREGS: lsls    r2, r2, #31278; NOREGS: moveq   r0, r1279; ONLYREGS: lsls    r0, r0, #31280; ONLYREGS: vmovne.f32      s1, s0281; HARD: lsls    r0, r0, #31282; VFP4-ALL: vmovne.f32      s1, s0283; VFP4-ALL: vmov.f32        s0, s1284; FP-ARMv8: vseleq.f32 s0, s1, s0285  %1 = select i1 %c, float %a, float %b286  ret float %1287}288 289define double @select_d(double %a, double %b, i1 %c) {290; CHECK-LABEL: select_d:291; NOREGS: ldr{{(.w)?}}     [[REG:r[0-9]+]], [sp]292; NOREGS: lsls.w    [[REG]], [[REG]], #31293; ONLYREGS: lsls    r0, r0, #31294; NOREGS-DAG: moveq   r0, r2295; NOREGS-DAG: moveq   r1, r3296; ONLYREGS-DAG: csel   r0, r2, r1297; ONLYREGS-DAG: csel   r1, r12, r3298; SP-DAG: vmov [[ALO:r[0-9]+]], [[AHI:r[0-9]+]], d0299; SP-DAG: vmov [[BLO:r[0-9]+]], [[BHI:r[0-9]+]], d1300; SP: lsls r0, r0, #31301; SP: itt ne302; SP-DAG: movne [[BLO]], [[ALO]]303; SP-DAG: movne [[BHI]], [[AHI]]304; SP: vmov d0, [[BLO]], [[BHI]]305; DP: lsls   r0, r0, #31306; VFP4-DP: vmovne.f64      d1, d0307; VFP4-DP: vmov.f64        d0, d1308; FP-ARMV8: vseleq.f64      d0, d1, d0309  %1 = select i1 %c, double %a, double %b310  ret double %1311}312