1; RUN: llc < %s -mtriple=armv8-eabi -mattr=+fullfp16 | FileCheck %s 2; RUN: llc < %s -mtriple thumbv7a -mattr=+fullfp16 | FileCheck %s 3 4; TODO: we can't pass half-precision arguments as "half" types yet. We do 5; that for the time being by passing "float %f.coerce" and the necessary 6; bitconverts/truncates. In these tests we pass i16 and use 1 bitconvert, which 7; is the shortest way to get a half type. But when we can pass half types, we 8; want to use that here. 9 10define half @fp16_vminnm_o(i16 signext %a, i16 signext %b) { 11; CHECK-LABEL: fp16_vminnm_o: 12; CHECK-NOT: vminnm.f16 13entry: 14 %0 = bitcast i16 %a to half 15 %1 = bitcast i16 %b to half 16 %cmp = fcmp olt half %0, %1 17 %cond = select i1 %cmp, half %0, half %1 18 ret half %cond 19} 20 21define half @fp16_vminnm_o_rev(i16 signext %a, i16 signext %b) { 22; CHECK-LABEL: fp16_vminnm_o_rev: 23; CHECK-NOT: vminnm.f16 24entry: 25 %0 = bitcast i16 %a to half 26 %1 = bitcast i16 %b to half 27 %cmp = fcmp ogt half %0, %1 28 %cond = select i1 %cmp, half %0, half %1 29 ret half %cond 30} 31 32define half @fp16_vminnm_u(i16 signext %a, i16 signext %b) { 33; CHECK-LABEL: fp16_vminnm_u: 34; CHECK-NOT: vminnm.f16 35entry: 36 %0 = bitcast i16 %a to half 37 %1 = bitcast i16 %b to half 38 %cmp = fcmp ult half %0, %1 39 %cond = select i1 %cmp, half %0, half %1 40 ret half %cond 41} 42 43define half @fp16_vminnm_ule(i16 signext %a, i16 signext %b) { 44; CHECK-LABEL: fp16_vminnm_ule: 45; CHECK-NOT: vminnm.f16 46entry: 47 %0 = bitcast i16 %a to half 48 %1 = bitcast i16 %b to half 49 %cmp = fcmp ule half %0, %1 50 %cond = select i1 %cmp, half %0, half %1 51 ret half %cond 52} 53 54define half @fp16_vminnm_u_rev(i16 signext %a, i16 signext %b) { 55; CHECK-LABEL: fp16_vminnm_u_rev: 56; CHECK-NOT: vminnm.f16 57entry: 58 %0 = bitcast i16 %a to half 59 %1 = bitcast i16 %b to half 60 %cmp = fcmp ugt half %0, %1 61 %cond = select i1 %cmp, half %1, half %0 62 ret half %cond 63} 64 65define half @fp16_vmaxnm_o(i16 signext %a, i16 signext %b) { 66; CHECK-LABEL: fp16_vmaxnm_o: 67; CHECK-NOT: vmaxnm.f16 68entry: 69 %0 = bitcast i16 %a to half 70 %1 = bitcast i16 %b to half 71 %cmp = fcmp ogt half %0, %1 72 %cond = select i1 %cmp, half %0, half %1 73 ret half %cond 74} 75 76define half @fp16_vmaxnm_oge(i16 signext %a, i16 signext %b) { 77; CHECK-LABEL: fp16_vmaxnm_oge: 78; CHECK-NOT: vmaxnm.f16 79entry: 80 %0 = bitcast i16 %a to half 81 %1 = bitcast i16 %b to half 82 %cmp = fcmp oge half %0, %1 83 %cond = select i1 %cmp, half %0, half %1 84 ret half %cond 85} 86 87define half @fp16_vmaxnm_o_rev(i16 signext %a, i16 signext %b) { 88; CHECK-LABEL: fp16_vmaxnm_o_rev: 89; CHECK-NOT: vmaxnm.f16 90entry: 91 %0 = bitcast i16 %a to half 92 %1 = bitcast i16 %b to half 93 %cmp = fcmp olt half %0, %1 94 %cond = select i1 %cmp, half %1, half %0 95 ret half %cond 96} 97 98define half @fp16_vmaxnm_ole_rev(i16 signext %a, i16 signext %b) { 99; CHECK-LABEL: fp16_vmaxnm_ole_rev: 100; CHECK-NOT: vmaxnm.f16 101entry: 102 %0 = bitcast i16 %a to half 103 %1 = bitcast i16 %b to half 104 %cmp = fcmp ole half %0, %1 105 %cond = select i1 %cmp, half %1, half %0 106 ret half %cond 107} 108 109define half @fp16_vmaxnm_u(i16 signext %a, i16 signext %b) { 110; CHECK-LABEL: fp16_vmaxnm_u: 111; CHECK-NOT: vmaxnm.f16 112entry: 113 %0 = bitcast i16 %a to half 114 %1 = bitcast i16 %b to half 115 %cmp = fcmp ugt half %0, %1 116 %cond = select i1 %cmp, half %0, half %1 117 ret half %cond 118} 119 120define half @fp16_vmaxnm_uge(i16 signext %a, i16 signext %b) { 121; CHECK-LABEL: fp16_vmaxnm_uge: 122; CHECK-NOT: vmaxnm.f16 123entry: 124 %0 = bitcast i16 %a to half 125 %1 = bitcast i16 %b to half 126 %cmp = fcmp uge half %0, %1 127 %cond = select i1 %cmp, half %0, half %1 128 ret half %cond 129} 130 131define half @fp16_vmaxnm_u_rev(i16 signext %a, i16 signext %b) { 132; CHECK-LABEL: fp16_vmaxnm_u_rev: 133; CHECK-NOT: vmaxnm.f16 134entry: 135 %0 = bitcast i16 %a to half 136 %1 = bitcast i16 %b to half 137 %cmp = fcmp ult half %0, %1 138 %cond = select i1 %cmp, half %1, half %0 139 ret half %cond 140} 141 142; known non-NaNs 143 144define half @fp16_vminnm_NNNo(i16 signext %a) { 145; CHECK-LABEL: fp16_vminnm_NNNo: 146; CHECK: vldr.16 [[S0:s[0-9]]], .LCPI{{.*}} 147; CHECK: vmov.f16 [[S2:s[0-9]]], #1.200000e+01 148; CHECK: vmov.f16 [[S4:s[0-9]]], r{{.}} 149; CHECK: vminnm.f16 s2, [[S4]], [[S2]] 150; CHECK: vmin.f16 d0, d1, d0 151entry: 152 %0 = bitcast i16 %a to half 153 %cmp1 = fcmp olt half %0, 12. 154 %cond1 = select i1 %cmp1, half %0, half 12. 155 %cmp2 = fcmp olt half 34., %cond1 156 %cond2 = select i1 %cmp2, half 34., half %cond1 157 ret half %cond2 158} 159 160define half @fp16_vminnm_NNNo_rev(i16 signext %a) { 161; CHECK-LABEL: fp16_vminnm_NNNo_rev: 162; CHECK: vldr.16 [[S0:s[0-9]]], .LCPI{{.*}} 163; CHECK: vmov.f16 [[S2:s[0-9]]], r{{.}} 164; CHECK: vmin.f16 d0, d1, d0 165; CHECK: vldr.16 [[S2:s[0-9]]], .LCPI{{.*}} 166; CHECK: vminnm.f16 s0, [[S0]], [[S2]] 167entry: 168 %0 = bitcast i16 %a to half 169 %cmp1 = fcmp ogt half %0, 56. 170 %cond1 = select i1 %cmp1, half 56., half %0 171 %cmp2 = fcmp ogt half 78., %cond1 172 %cond2 = select i1 %cmp2, half %cond1, half 78. 173 ret half %cond2 174} 175 176define half @fp16_vminnm_NNNu(i16 signext %b) { 177; CHECK-LABEL: fp16_vminnm_NNNu: 178; CHECK: vldr.16 [[S0:s[0-9]]], .LCPI{{.*}} 179; CHECK: vmov.f16 [[S2:s[0-9]]], #1.200000e+01 180; CHECK: vmov.f16 [[S4:s[0-9]]], r{{.}} 181; CHECK: vminnm.f16 s2, [[S4]], [[S2]] 182; CHECK: vmin.f16 d0, d1, d0 183entry: 184 %0 = bitcast i16 %b to half 185 %cmp1 = fcmp ult half 12., %0 186 %cond1 = select i1 %cmp1, half 12., half %0 187 %cmp2 = fcmp ult half %cond1, 34. 188 %cond2 = select i1 %cmp2, half %cond1, half 34. 189 ret half %cond2 190} 191 192define half @fp16_vminnm_NNNule(i16 signext %b) { 193; CHECK-LABEL: fp16_vminnm_NNNule: 194; CHECK: vldr.16 [[S2:s[0-9]]], .LCPI{{.*}} 195; CHECK: vmov.f16 [[S4:s[0-9]]], r{{.}} 196; CHECK: vldr.16 [[S0:s[0-9]]], .LCPI{{.*}} 197; CHECK: vminnm.f16 s2, [[S4]], [[S2]] 198; CHECK: vmin.f16 d0, d1, d0 199 200entry: 201 %0 = bitcast i16 %b to half 202 %cmp1 = fcmp ule half 34., %0 203 %cond1 = select i1 %cmp1, half 34., half %0 204 %cmp2 = fcmp ule half %cond1, 56. 205 %cond2 = select i1 %cmp2, half %cond1, half 56. 206 ret half %cond2 207} 208 209define half @fp16_vminnm_NNNu_rev(i16 signext %b) { 210; CHECK-LABEL: fp16_vminnm_NNNu_rev: 211 212; CHECK: vldr.16 [[S0:s[0-9]]], .LCPI{{.*}} 213; CHECK: vmov.f16 [[S2:s[0-9]]], r{{.}} 214; CHECK: vmin.f16 d0, d1, d0 215; CHECK: vldr.16 [[S2:s[0-9]]], .LCPI{{.*}} 216; CHECK: vminnm.f16 s0, [[S0]], [[S2]] 217 218entry: 219 %0 = bitcast i16 %b to half 220 %cmp1 = fcmp ugt half 56., %0 221 %cond1 = select i1 %cmp1, half %0, half 56. 222 %cmp2 = fcmp ugt half %cond1, 78. 223 %cond2 = select i1 %cmp2, half 78., half %cond1 224 ret half %cond2 225} 226 227define half @fp16_vmaxnm_NNNo(i16 signext %a) { 228; CHECK-LABEL: fp16_vmaxnm_NNNo: 229; CHECK: vldr.16 [[S0:s[0-9]]], .LCPI{{.*}} 230; CHECK: vmov.f16 [[S2:s[0-9]]], #1.200000e+01 231; CHECK: vmov.f16 [[S4:s[0-9]]], r{{.}} 232; CHECK: vmaxnm.f16 s2, [[S4]], [[S2]] 233; CHECK: vmax.f16 d0, d1, d0 234entry: 235 %0 = bitcast i16 %a to half 236 %cmp1 = fcmp ogt half %0, 12. 237 %cond1 = select i1 %cmp1, half %0, half 12. 238 %cmp2 = fcmp ogt half 34., %cond1 239 %cond2 = select i1 %cmp2, half 34., half %cond1 240 ret half %cond2 241} 242 243define half @fp16_vmaxnm_NNNoge(i16 signext %a) { 244; CHECK-LABEL: fp16_vmaxnm_NNNoge: 245; CHECK: vldr.16 [[S2:s[0-9]]], .LCPI{{.*}} 246; CHECK: vmov.f16 [[S4:s[0-9]]], r{{.}} 247; CHECK: vldr.16 [[S0:s[0-9]]], .LCPI{{.*}} 248; CHECK: vmaxnm.f16 s2, [[S4]], [[S2]] 249; CHECK: vmax.f16 d0, d1, d0 250entry: 251 %0 = bitcast i16 %a to half 252 %cmp1 = fcmp oge half %0, 34. 253 %cond1 = select i1 %cmp1, half %0, half 34. 254 %cmp2 = fcmp oge half 56., %cond1 255 %cond2 = select i1 %cmp2, half 56., half %cond1 256 ret half %cond2 257} 258 259define half @fp16_vmaxnm_NNNo_rev(i16 signext %a) { 260; CHECK-LABEL: fp16_vmaxnm_NNNo_rev: 261; CHECK: vldr.16 [[S0:s[0-9]]], .LCPI{{.*}} 262; CHECK: vmov.f16 [[S2:s[0-9]]], r{{.}} 263; CHECK: vmax.f16 d0, d1, d0 264; CHECK: vldr.16 [[S2:s[0-9]]], .LCPI{{.*}} 265; CHECK: vmaxnm.f16 s0, [[S0]], [[S2]] 266entry: 267 %0 = bitcast i16 %a to half 268 %cmp1 = fcmp olt half %0, 56. 269 %cond1 = select i1 %cmp1, half 56., half %0 270 %cmp2 = fcmp olt half 78., %cond1 271 %cond2 = select i1 %cmp2, half %cond1, half 78. 272 ret half %cond2 273} 274 275define half @fp16_vmaxnm_NNNole_rev(i16 signext %a) { 276; CHECK-LABEL: fp16_vmaxnm_NNNole_rev: 277; CHECK: vldr.16 [[S0:s[0-9]]], .LCPI{{.*}} 278; CHECK: vmov.f16 [[S2:s[0-9]]], r{{.}} 279; CHECK: vmax.f16 d0, d1, d0 280; CHECK: vldr.16 [[S2:s[0-9]]], .LCPI{{.*}} 281; CHECK: vmaxnm.f16 s0, [[S0]], [[S2]] 282entry: 283 %0 = bitcast i16 %a to half 284 %cmp1 = fcmp ole half %0, 78. 285 %cond1 = select i1 %cmp1, half 78., half %0 286 %cmp2 = fcmp ole half 90., %cond1 287 %cond2 = select i1 %cmp2, half %cond1, half 90. 288 ret half %cond2 289} 290 291define half @fp16_vmaxnm_NNNu(i16 signext %b) { 292; CHECK-LABEL: fp16_vmaxnm_NNNu: 293; CHECK: vldr.16 [[S0:s[0-9]]], .LCPI{{.*}} 294; CHECK: vmov.f16 [[S2:s[0-9]]], #1.200000e+01 295; CHECK: vmov.f16 [[S4:s[0-9]]], r{{.}} 296; CHECK: vmaxnm.f16 s2, [[S4]], [[S2]] 297; CHECK: vmax.f16 d0, d1, d0 298entry: 299 %0 = bitcast i16 %b to half 300 %cmp1 = fcmp ugt half 12., %0 301 %cond1 = select i1 %cmp1, half 12., half %0 302 %cmp2 = fcmp ugt half %cond1, 34. 303 %cond2 = select i1 %cmp2, half %cond1, half 34. 304 ret half %cond2 305} 306 307define half @fp16_vmaxnm_NNNuge(i16 signext %b) { 308; CHECK-LABEL: fp16_vmaxnm_NNNuge: 309; CHECK: vldr.16 [[S2:s[0-9]]], .LCPI{{.*}} 310; CHECK: vmov.f16 [[S4:s[0-9]]], r{{.}} 311; CHECK: vldr.16 [[S0:s[0-9]]], .LCPI{{.*}} 312; CHECK: vmaxnm.f16 s2, [[S4]], [[S2]] 313; CHECK: vmax.f16 d0, d1, d0 314entry: 315 %0 = bitcast i16 %b to half 316 %cmp1 = fcmp uge half 34., %0 317 %cond1 = select i1 %cmp1, half 34., half %0 318 %cmp2 = fcmp uge half %cond1, 56. 319 %cond2 = select i1 %cmp2, half %cond1, half 56. 320 ret half %cond2 321} 322 323define half @fp16_vminmaxnm_neg0(i16 signext %a) { 324; CHECK-LABEL: fp16_vminmaxnm_neg0: 325; CHECK: vldr.16 [[S0:s[0-9]]], .LCPI{{.*}} 326; CHECK: vmov.f16 [[S2:s[0-9]]], r{{.}} 327; CHECK: vminnm.f16 s2, [[S2]], [[S0]] 328; CHECK: vmax.f16 d0, d1, d0 329entry: 330 %0 = bitcast i16 %a to half 331 %cmp1 = fcmp olt half %0, -0. 332 %cond1 = select i1 %cmp1, half %0, half -0. 333 %cmp2 = fcmp ugt half %cond1, -0. 334 %cond2 = select i1 %cmp2, half %cond1, half -0. 335 ret half %cond2 336} 337 338define half @fp16_vminmaxnm_e_0(i16 signext %a) { 339; CHECK-LABEL: fp16_vminmaxnm_e_0: 340; CHECK: vldr.16 [[S2:s[0-9]]], .LCPI{{.*}} 341; CHECK: vmov.f16 [[S0:s[0-9]]], r{{.}} 342; CHECK: vmin.f16 d0, d0, d1 343; CHECK: vmaxnm.f16 s0, [[S0]], [[S2]] 344entry: 345 %0 = bitcast i16 %a to half 346 %cmp1 = fcmp nsz ole half 0., %0 347 %cond1 = select i1 %cmp1, half 0., half %0 348 %cmp2 = fcmp nsz uge half 0., %cond1 349 %cond2 = select i1 %cmp2, half 0., half %cond1 350 ret half %cond2 351} 352 353define half @fp16_vminmaxnm_e_neg0(i16 signext %a) { 354; CHECK-LABEL: fp16_vminmaxnm_e_neg0: 355; CHECK: vldr.16 [[S0:s[0-9]]], .LCPI{{.*}} 356; CHECK: vmov.f16 [[S2:s[0-9]]], r{{.}} 357; CHECK: vminnm.f16 s2, [[S2]], [[S0]] 358; CHECK: vmax.f16 d0, d1, d0 359entry: 360 %0 = bitcast i16 %a to half 361 %cmp1 = fcmp nsz ule half -0., %0 362 %cond1 = select i1 %cmp1, half -0., half %0 363 %cmp2 = fcmp nsz oge half -0., %cond1 364 %cond2 = select i1 %cmp2, half -0., half %cond1 365 ret half %cond2 366} 367