1; RUN: llc -mtriple=armv7 -mattr=+neon -mcpu=swift %s -o - | FileCheck %s 2; RUN: llc -mtriple=armv7 -mattr=+neon -mcpu=cortex-a8 %s -o - | FileCheck --check-prefix=CHECK-NONEONFP %s 3; RUN: llc -mtriple=armv7 -mattr=-neon -mcpu=cortex-a8 %s -o - | FileCheck --check-prefix=CHECK-NONEON %s 4 5; RUN: llc -mtriple=thumbv7m -mcpu=cortex-m4 %s -o - \ 6; RUN: | FileCheck --check-prefix=CHECK-NO-XO %s 7 8; RUN: llc -mtriple=thumbv7m -mattr=+execute-only -mcpu=cortex-m4 %s -o - \ 9; RUN: | FileCheck --check-prefix=CHECK-XO-FLOAT --check-prefix=CHECK-XO-DOUBLE %s 10 11; RUN: llc -mtriple=thumbv7meb -mattr=+execute-only -mcpu=cortex-m4 %s -o - \ 12; RUN: | FileCheck --check-prefix=CHECK-XO-FLOAT --check-prefix=CHECK-XO-DOUBLE-BE --check-prefix=CHECK-XO-DOUBLE-BE-FPREGS %s 13 14; RUN: llc -mtriple=thumbv7meb -mattr=+execute-only -mcpu=cortex-m3 %s -o - \ 15; RUN: | FileCheck --check-prefix=CHECK-XO-DOUBLE-BE %s 16 17; RUN: llc -mtriple=thumbv7m -mattr=+execute-only -mcpu=cortex-m4 -relocation-model=ropi %s -o - \ 18; RUN: | FileCheck --check-prefix=CHECK-XO-ROPI %s 19 20; RUN: llc -mtriple=thumbv8m.main -mattr=fp-armv8 %s -o - \ 21; RUN: | FileCheck --check-prefix=CHECK-NO-XO %s 22 23; RUN: llc -mtriple=thumbv8m.main -mattr=+execute-only -mattr=fp-armv8 %s -o - \ 24; RUN: | FileCheck --check-prefix=CHECK-XO-FLOAT --check-prefix=CHECK-XO-DOUBLE %s 25 26; RUN: llc -mtriple=thumbv8m.maineb -mattr=+execute-only -mattr=fp-armv8 %s -o - \ 27; RUN: | FileCheck --check-prefix=CHECK-XO-FLOAT --check-prefix=CHECK-XO-DOUBLE-BE %s 28 29; RUN: llc -mtriple=thumbv8m.main -mattr=+execute-only -mattr=fp-armv8 -relocation-model=ropi %s -o - \ 30; RUN: | FileCheck --check-prefix=CHECK-XO-ROPI %s 31 32define arm_aapcs_vfpcc float @test_vmov_f32() { 33; CHECK-LABEL: test_vmov_f32: 34; CHECK: vmov.f32 d0, #1.0 35 36; CHECK-NONEONFP: vmov.f32 s0, #1.0 37 ret float 1.0 38} 39 40define arm_aapcs_vfpcc float @test_vmov_imm() { 41; CHECK-LABEL: test_vmov_imm: 42; CHECK: vmov.i32 d0, #0 43 44; CHECK-NONEON-LABEL: test_vmov_imm: 45; CHECK-NONEON: vldr s0, {{.?LCPI[0-9]+_[0-9]+}} 46 47; CHECK-NO-XO-LABEL: test_vmov_imm: 48; CHECK-NO-XO: vldr s0, {{.?LCPI[0-9]+_[0-9]+}} 49 50; CHECK-XO-FLOAT-LABEL: test_vmov_imm: 51; CHECK-XO-FLOAT: movs [[REG:r[0-9]+]], #0 52; CHECK-XO-FLOAT: vmov {{s[0-9]+}}, [[REG]] 53; CHECK-XO-FLOAT-NOT: vldr 54 ret float 0.0 55} 56 57define arm_aapcs_vfpcc float @test_vmvn_imm() { 58; CHECK-LABEL: test_vmvn_imm: 59; CHECK: vmvn.i32 d0, #0xb0000000 60 61; CHECK-NONEON-LABEL: test_vmvn_imm: 62; CHECK-NONEON: vldr s0, {{.?LCPI[0-9]+_[0-9]+}} 63 64; CHECK-NO-XO-LABEL: test_vmvn_imm: 65; CHECK-NO-XO: vldr s0, {{.?LCPI[0-9]+_[0-9]+}} 66 67; CHECK-XO-FLOAT-LABEL: test_vmvn_imm: 68; CHECK-XO-FLOAT: mvn [[REG:r[0-9]+]], #-1342177280 69; CHECK-XO-FLOAT: vmov {{s[0-9]+}}, [[REG]] 70; CHECK-XO-FLOAT-NOT: vldr 71 ret float 8589934080.0 72} 73 74define arm_aapcs_vfpcc double @test_vmov_f64() { 75; CHECK-LABEL: test_vmov_f64: 76; CHECK: vmov.f64 d0, #1.0 77 78; CHECK-NONEON-LABEL: test_vmov_f64: 79; CHECK-NONEON: vmov.f64 d0, #1.0 80 81 ret double 1.0 82} 83 84define arm_aapcs_vfpcc double @test_vmov_double_imm() { 85; CHECK-LABEL: test_vmov_double_imm: 86; CHECK: vmov.i32 d0, #0 87 88; CHECK-NONEON-LABEL: test_vmov_double_imm: 89; CHECK-NONEON: vldr d0, {{.?LCPI[0-9]+_[0-9]+}} 90 91; CHECK-NO-XO-LABEL: test_vmov_double_imm: 92; CHECK-NO-XO: vldr d0, {{.?LCPI[0-9]+_[0-9]+}} 93 94; CHECK-XO-DOUBLE-LABEL: test_vmov_double_imm: 95; CHECK-XO-DOUBLE: movs [[REG:r[0-9]+]], #0 96; CHECK-XO-DOUBLE: vmov {{d[0-9]+}}, [[REG]], [[REG]] 97; CHECK-XO-DOUBLE-NOT: vldr 98 99; CHECK-XO-DOUBLE-BE-LABEL: test_vmov_double_imm: 100; CHECK-XO-DOUBLE-BE-FPREGS: movs [[REG:r[0-9]+]], #0 101; CHECK-XO-DOUBLE-BE-FPREGS: vmov {{d[0-9]+}}, [[REG]], [[REG]] 102; CHECK-XO-DOUBLE-NOT: vldr 103 ret double 0.0 104} 105 106define arm_aapcs_vfpcc double @test_vmvn_double_imm() { 107; CHECK-LABEL: test_vmvn_double_imm: 108; CHECK: vmvn.i32 d0, #0xb0000000 109 110; CHECK-NONEON-LABEL: test_vmvn_double_imm: 111; CHECK-NONEON: vldr d0, {{.?LCPI[0-9]+_[0-9]+}} 112 113; CHECK-NO-XO-LABEL: test_vmvn_double_imm: 114; CHECK-NO-XO: vldr d0, {{.?LCPI[0-9]+_[0-9]+}} 115 116; CHECK-XO-DOUBLE-LABEL: test_vmvn_double_imm: 117; CHECK-XO-DOUBLE: mvn [[REG:r[0-9]+]], #-1342177280 118; CHECK-XO-DOUBLE: vmov {{d[0-9]+}}, [[REG]], [[REG]] 119; CHECK-XO-DOUBLE-NOT: vldr 120 121; CHECK-XO-DOUBLE-BE-LABEL: test_vmvn_double_imm: 122; CHECK-XO-DOUBLE-BE-FPREGS: mvn [[REG:r[0-9]+]], #-1342177280 123; CHECK-XO-DOUBLE-BE-FPREGS: vmov {{d[0-9]+}}, [[REG]], [[REG]] 124; CHECK-XO-DOUBLE-BE-NOT: vldr 125 ret double 0x4fffffff4fffffff 126} 127 128; Make sure we don't ignore the high half of 64-bit values when deciding whether 129; a vmov/vmvn is possible. 130define arm_aapcs_vfpcc double @test_notvmvn_double_imm() { 131; CHECK-LABEL: test_notvmvn_double_imm: 132; CHECK: vldr d0, {{.?LCPI[0-9]+_[0-9]+}} 133 134; CHECK-NONEON-LABEL: test_notvmvn_double_imm: 135; CHECK-NONEON: vldr d0, {{.?LCPI[0-9]+_[0-9]+}} 136 137; CHECK-NO-XO-LABEL: test_notvmvn_double_imm: 138; CHECK-NO-XO: vldr d0, {{.?LCPI[0-9]+_[0-9]+}} 139 140; CHECK-XO-DOUBLE-LABEL: test_notvmvn_double_imm: 141; CHECK-XO-DOUBLE: mvn [[REG1:r[0-9]+]], #-1342177280 142; CHECK-XO-DOUBLE: mov.w [[REG2:r[0-9]+]], #-1 143; CHECK-XO-DOUBLE: vmov {{d[0-9]+}}, [[REG2]], [[REG1]] 144; CHECK-XO-DOUBLE-NOT: vldr 145 146; CHECK-XO-DOUBLE-BE-LABEL: test_notvmvn_double_imm: 147; CHECK-XO-DOUBLE-BE: mvn [[REG1:r[0-9]+]], #-1342177280 148; CHECK-XO-DOUBLE-BE: mov.w [[REG2:r[0-9]+]], #-1 149; CHECK-XO-DOUBLE-BE-FPREGS: vmov {{d[0-9]+}}, [[REG2]], [[REG1]] 150; CHECK-XO-DOUBLE-BE-NOT: vldr 151 ret double 0x4fffffffffffffff 152} 153 154define arm_aapcs_vfpcc float @lower_const_f32_xo() { 155; CHECK-NO-XO-LABEL: lower_const_f32_xo 156; CHECK-NO-XO: vldr {{s[0-9]+}}, {{.?LCPI[0-9]+_[0-9]+}} 157 158; CHECK-XO-FLOAT-LABEL: lower_const_f32_xo 159; CHECK-XO-FLOAT: movw [[REG:r[0-9]+]], #29884 160; CHECK-XO-FLOAT: movt [[REG]], #16083 161; CHECK-XO-FLOAT: vmov {{s[0-9]+}}, [[REG]] 162; CHECK-XO-FLOAT-NOT: vldr 163 ret float 0x3FDA6E9780000000 164} 165 166define arm_aapcs_vfpcc double @lower_const_f64_xo() { 167; CHECK-NO-XO-LABEL: lower_const_f64_xo 168; CHECK-NO-XO: vldr {{d[0-9]+}}, {{.?LCPI[0-9]+_[0-9]+}} 169 170; CHECK-XO-DOUBLE-LABEL: lower_const_f64_xo 171; CHECK-XO-DOUBLE: movw [[REG1:r[0-9]+]], #6291 172; CHECK-XO-DOUBLE: movw [[REG2:r[0-9]+]], #27263 173; CHECK-XO-DOUBLE: movt [[REG1]], #16340 174; CHECK-XO-DOUBLE: movt [[REG2]], #29884 175; CHECK-XO-DOUBLE: vmov {{d[0-9]+}}, [[REG2]], [[REG1]] 176; CHECK-XO-DOUBLE-NOT: vldr 177 178; CHECK-XO-DOUBLE-BE-LABEL: lower_const_f64_xo 179; CHECK-XO-DOUBLE-BE: movw [[REG1:r[0-9]+]], #6291 180; CHECK-XO-DOUBLE-BE: movw [[REG2:r[0-9]+]], #27263 181; CHECK-XO-DOUBLE-BE: movt [[REG1]], #16340 182; CHECK-XO-DOUBLE-BE: movt [[REG2]], #29884 183; CHECK-XO-DOUBLE-BE-FPREGS: vmov {{d[0-9]+}}, [[REG2]], [[REG1]] 184; CHECK-XO-DOUBLE-BE-NOT: vldr 185 ret double 3.140000e-01 186} 187 188; This is a target independent optimization, performed by the 189; DAG Combiner, which promotes floating point literals into 190; constant pools: 191; 192; (a cond b) ? 1.0f : 2.0f -> load (ConstPoolAddr + ((a cond b) ? 0 : 4) 193; 194; We need to make sure that the constant pools are placed in 195; the data section when generating execute-only code: 196 197define arm_aapcs_vfpcc float @lower_fpconst_select(float %f) { 198 199; CHECK-NO-XO-LABEL: lower_fpconst_select 200; CHECK-NO-XO: adr [[REG:r[0-9]+]], [[LABEL:.?LCPI[0-9]+_[0-9]+]] 201; CHECK-NO-XO: vldr {{s[0-9]+}}, {{[[]}}[[REG]]{{[]]}} 202; CHECK-NO-XO-NOT: .rodata 203; CHECK-NO-XO: [[LABEL]]: 204; CHECK-NO-XO: .long 0x4f9502f9 205; CHECK-NO-XO: .long 0x4dee6b28 206 207; CHECK-XO-FLOAT-LABEL: lower_fpconst_select 208; CHECK-XO-FLOAT: movw [[REG:r[0-9]+]], :lower16:[[LABEL:.?LCP[0-9]+_[0-9]+]] 209; CHECK-XO-FLOAT: movt [[REG]], :upper16:[[LABEL]] 210; CHECK-XO-FLOAT: vldr {{s[0-9]+}}, {{[[]}}[[REG]]{{[]]}} 211; CHECK-XO-FLOAT: .rodata 212; CHECK-XO-FLOAT-NOT: .text 213; CHECK-XO-FLOAT: [[LABEL]]: 214; CHECK-XO-FLOAT: .long 0x4f9502f9 215; CHECK-XO-FLOAT: .long 0x4dee6b28 216 217; CHECK-XO-ROPI-LABEL: lower_fpconst_select 218; CHECK-XO-ROPI: movw [[REG:r[0-9]+]], :lower16:([[LABEL1:.?LCP[0-9]+_[0-9]+]]-([[LABEL2:.?LPC[0-9]+_[0-9]+]]+4)) 219; CHECK-XO-ROPI: movt [[REG]], :upper16:([[LABEL1]]-([[LABEL2]]+4)) 220; CHECK-XO-ROPI: [[LABEL2]]: 221; CHECK-XO-ROPI: vldr {{s[0-9]+}}, {{[[]}}[[REG]]{{[]]}} 222; CHECK-XO-ROPI: .rodata 223; CHECK-XO-ROPI-NOT: .text 224; CHECK-XO-ROPI: [[LABEL1]]: 225; CHECK-XO-ROPI: .long 0x4f9502f9 226; CHECK-XO-ROPI: .long 0x4dee6b28 227 228 %cmp = fcmp nnan oeq float %f, 0.000000e+00 229 %sel = select i1 %cmp, float 5.000000e+08, float 5.000000e+09 230 ret float %sel 231} 232