1; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py 2; RUN: llc -mtriple=arm-- -mattr=+mve.fp < %s | FileCheck %s 3 4define float @fadd_select_fneg_fneg_f32(i32 %arg0, float %x, float %y, float %z) { 5; CHECK-LABEL: fadd_select_fneg_fneg_f32: 6; CHECK: @ %bb.0: 7; CHECK-NEXT: vmov s0, r2 8; CHECK-NEXT: cmp r0, #0 9; CHECK-NEXT: vmov s4, r1 10; CHECK-NEXT: vmov s2, r3 11; CHECK-NEXT: vseleq.f32 s0, s4, s0 12; CHECK-NEXT: vsub.f32 s0, s2, s0 13; CHECK-NEXT: vmov r0, s0 14; CHECK-NEXT: bx lr 15 %cmp = icmp eq i32 %arg0, 0 16 %neg.x = fneg float %x 17 %neg.y = fneg float %y 18 %select = select i1 %cmp, float %neg.x, float %neg.y 19 %add = fadd float %select, %z 20 ret float %add 21} 22 23define half @fadd_select_fneg_fneg_f16(i32 %arg0, half %x, half %y, half %z) { 24; CHECK-LABEL: fadd_select_fneg_fneg_f16: 25; CHECK: @ %bb.0: 26; CHECK-NEXT: vmov.f16 s0, r2 27; CHECK-NEXT: cmp r0, #0 28; CHECK-NEXT: vmov.f16 s2, r1 29; CHECK-NEXT: vseleq.f16 s0, s2, s0 30; CHECK-NEXT: vmov.f16 s2, r3 31; CHECK-NEXT: vsub.f16 s0, s2, s0 32; CHECK-NEXT: vmov r0, s0 33; CHECK-NEXT: bx lr 34 %cmp = icmp eq i32 %arg0, 0 35 %neg.x = fneg half %x 36 %neg.y = fneg half %y 37 %select = select i1 %cmp, half %neg.x, half %neg.y 38 %add = fadd half %select, %z 39 ret half %add 40} 41 42define <2 x float> @fadd_select_fneg_fneg_v2f32(i32 %arg0, <2 x float> %x, <2 x float> %y, <2 x float> %z) { 43; CHECK-LABEL: fadd_select_fneg_fneg_v2f32: 44; CHECK: @ %bb.0: 45; CHECK-NEXT: add r1, sp, #24 46; CHECK-NEXT: cmp r0, #0 47; CHECK-NEXT: vldrw.u32 q0, [r1] 48; CHECK-NEXT: beq .LBB2_2 49; CHECK-NEXT: @ %bb.1: @ %select.false 50; CHECK-NEXT: add r0, sp, #8 51; CHECK-NEXT: vldrw.u32 q1, [r0] 52; CHECK-NEXT: b .LBB2_3 53; CHECK-NEXT: .LBB2_2: 54; CHECK-NEXT: vmov d2, r2, r3 55; CHECK-NEXT: .LBB2_3: @ %select.end 56; CHECK-NEXT: vneg.f32 q1, q1 57; CHECK-NEXT: vadd.f32 q0, q1, q0 58; CHECK-NEXT: vmov r0, r1, d0 59; CHECK-NEXT: vmov r2, r3, d1 60; CHECK-NEXT: bx lr 61 %cmp = icmp eq i32 %arg0, 0 62 %neg.x = fneg <2 x float> %x 63 %neg.y = fneg <2 x float> %y 64 %select = select i1 %cmp, <2 x float> %neg.x, <2 x float> %neg.y 65 %add = fadd <2 x float> %select, %z 66 ret <2 x float> %add 67} 68 69define <2 x half> @fadd_select_fneg_fneg_v2f16(i32 %arg0, <2 x half> %x, <2 x half> %y, <2 x half> %z) { 70; CHECK-LABEL: fadd_select_fneg_fneg_v2f16: 71; CHECK: @ %bb.0: 72; CHECK-NEXT: add r1, sp, #24 73; CHECK-NEXT: cmp r0, #0 74; CHECK-NEXT: vldrw.u32 q0, [r1] 75; CHECK-NEXT: beq .LBB3_2 76; CHECK-NEXT: @ %bb.1: @ %select.false 77; CHECK-NEXT: add r0, sp, #8 78; CHECK-NEXT: vldrw.u32 q1, [r0] 79; CHECK-NEXT: b .LBB3_3 80; CHECK-NEXT: .LBB3_2: 81; CHECK-NEXT: vmov d2, r2, r3 82; CHECK-NEXT: .LBB3_3: @ %select.end 83; CHECK-NEXT: vneg.f16 q1, q1 84; CHECK-NEXT: vadd.f16 q0, q1, q0 85; CHECK-NEXT: vmov r0, r1, d0 86; CHECK-NEXT: vmov r2, r3, d1 87; CHECK-NEXT: bx lr 88 %cmp = icmp eq i32 %arg0, 0 89 %neg.x = fneg <2 x half> %x 90 %neg.y = fneg <2 x half> %y 91 %select = select i1 %cmp, <2 x half> %neg.x, <2 x half> %neg.y 92 %add = fadd <2 x half> %select, %z 93 ret <2 x half> %add 94} 95 96define float @fadd_select_fsub_fsub_f32(i32 %arg0, float %x, float %y, float %z) { 97; CHECK-LABEL: fadd_select_fsub_fsub_f32: 98; CHECK: @ %bb.0: 99; CHECK-NEXT: vmov.f32 s0, #2.000000e+00 100; CHECK-NEXT: cmp r0, #0 101; CHECK-NEXT: vmov s4, r2 102; CHECK-NEXT: vmov s2, r1 103; CHECK-NEXT: vmov s6, r3 104; CHECK-NEXT: vsub.f32 s4, s4, s0 105; CHECK-NEXT: vsub.f32 s0, s2, s0 106; CHECK-NEXT: vseleq.f32 s0, s0, s4 107; CHECK-NEXT: vadd.f32 s0, s0, s6 108; CHECK-NEXT: vmov r0, s0 109; CHECK-NEXT: bx lr 110 %cmp = icmp eq i32 %arg0, 0 111 %neg.x = fsub nsz float %x, 2.0 112 %neg.y = fsub nsz float %y, 2.0 113 %select = select i1 %cmp, float %neg.x, float %neg.y 114 %add = fadd float %select, %z 115 ret float %add 116} 117 118define float @fneg_select_fmul_fmul_f32(i32 %arg0, float %x, float %y) { 119; CHECK-LABEL: fneg_select_fmul_fmul_f32: 120; CHECK: @ %bb.0: 121; CHECK-NEXT: vmov.f32 s0, #4.000000e+00 122; CHECK-NEXT: cmp r0, #0 123; CHECK-NEXT: vmov.f32 s2, #8.000000e+00 124; CHECK-NEXT: vmov s4, r2 125; CHECK-NEXT: vmov s6, r1 126; CHECK-NEXT: vmul.f32 s0, s4, s0 127; CHECK-NEXT: vmul.f32 s2, s6, s2 128; CHECK-NEXT: vseleq.f32 s0, s2, s0 129; CHECK-NEXT: vmov r0, s0 130; CHECK-NEXT: eor r0, r0, #-2147483648 131; CHECK-NEXT: bx lr 132 %cmp = icmp eq i32 %arg0, 0 133 %neg.x = fmul float %x, 8.0 134 %neg.y = fmul float %y, 4.0 135 %select = select i1 %cmp, float %neg.x, float %neg.y 136 %neg = fneg float %select 137 ret float %neg 138} 139 140define half @fadd_select_fsub_fsub_f16(i32 %arg0, half %x, half %y, half %z) { 141; CHECK-LABEL: fadd_select_fsub_fsub_f16: 142; CHECK: @ %bb.0: 143; CHECK-NEXT: vmov.f16 s0, r2 144; CHECK-NEXT: vmov.f16 s2, #2.000000e+00 145; CHECK-NEXT: vmov.f16 s4, r1 146; CHECK-NEXT: vsub.f16 s0, s0, s2 147; CHECK-NEXT: vsub.f16 s2, s4, s2 148; CHECK-NEXT: cmp r0, #0 149; CHECK-NEXT: vseleq.f16 s0, s2, s0 150; CHECK-NEXT: vmov.f16 s2, r3 151; CHECK-NEXT: vadd.f16 s0, s0, s2 152; CHECK-NEXT: vmov r0, s0 153; CHECK-NEXT: bx lr 154 %cmp = icmp eq i32 %arg0, 0 155 %sub.x = fsub nsz half %x, 2.0 156 %sub.y = fsub nsz half %y, 2.0 157 %select = select i1 %cmp, half %sub.x, half %sub.y 158 %add = fadd half %select, %z 159 ret half %add 160} 161 162define half @fneg_select_fmul_fmul_f16(i32 %arg0, half %x, half %y) { 163; CHECK-LABEL: fneg_select_fmul_fmul_f16: 164; CHECK: @ %bb.0: 165; CHECK-NEXT: vmov.f16 s0, r2 166; CHECK-NEXT: vmov.f16 s2, #4.000000e+00 167; CHECK-NEXT: vmul.f16 s0, s0, s2 168; CHECK-NEXT: vmov.f16 s2, r1 169; CHECK-NEXT: vmov.f16 s4, #8.000000e+00 170; CHECK-NEXT: cmp r0, #0 171; CHECK-NEXT: vmul.f16 s2, s2, s4 172; CHECK-NEXT: vseleq.f16 s0, s2, s0 173; CHECK-NEXT: vneg.f16 s0, s0 174; CHECK-NEXT: vmov r0, s0 175; CHECK-NEXT: bx lr 176 %cmp = icmp eq i32 %arg0, 0 177 %mul.x = fmul half %x, 8.0 178 %mul.y = fmul half %y, 4.0 179 %select = select i1 %cmp, half %mul.x, half %mul.y 180 %neg = fneg half %select 181 ret half %neg 182} 183 184define half @fadd_select_fsub_arg_f16(i32 %arg0, half %x, half %y, half %z) { 185; CHECK-LABEL: fadd_select_fsub_arg_f16: 186; CHECK: @ %bb.0: 187; CHECK-NEXT: vmov.f16 s0, r1 188; CHECK-NEXT: vmov.f16 s2, #-2.000000e+00 189; CHECK-NEXT: vadd.f16 s0, s0, s2 190; CHECK-NEXT: vmov.f16 s2, r2 191; CHECK-NEXT: cmp r0, #0 192; CHECK-NEXT: vseleq.f16 s0, s0, s2 193; CHECK-NEXT: vmov.f16 s2, r3 194; CHECK-NEXT: vadd.f16 s0, s0, s2 195; CHECK-NEXT: vmov r0, s0 196; CHECK-NEXT: bx lr 197 %cmp = icmp eq i32 %arg0, 0 198 %sub.x = fsub nsz half %x, 2.0 199 %select = select i1 %cmp, half %sub.x, half %y 200 %add = fadd half %select, %z 201 ret half %add 202} 203 204define half @fadd_select_arg_fsub_f16(i32 %arg0, half %x, half %y, half %z) { 205; CHECK-LABEL: fadd_select_arg_fsub_f16: 206; CHECK: @ %bb.0: 207; CHECK-NEXT: vmov.f16 s0, r2 208; CHECK-NEXT: vmov.f16 s2, #-2.000000e+00 209; CHECK-NEXT: vadd.f16 s0, s0, s2 210; CHECK-NEXT: vmov.f16 s2, r1 211; CHECK-NEXT: cmp r0, #0 212; CHECK-NEXT: vseleq.f16 s0, s2, s0 213; CHECK-NEXT: vmov.f16 s2, r3 214; CHECK-NEXT: vadd.f16 s0, s0, s2 215; CHECK-NEXT: vmov r0, s0 216; CHECK-NEXT: bx lr 217 %cmp = icmp eq i32 %arg0, 0 218 %sub.y = fsub nsz half %y, 2.0 219 %select = select i1 %cmp, half %x, half %sub.y 220 %add = fadd half %select, %z 221 ret half %add 222} 223 224define half @fadd_select_fsub_select_f16(i32 %arg0, half %x, half %y, half %z) { 225; CHECK-LABEL: fadd_select_fsub_select_f16: 226; CHECK: @ %bb.0: 227; CHECK-NEXT: vmov.f16 s0, r1 228; CHECK-NEXT: vmov.f16 s2, #2.000000e+00 229; CHECK-NEXT: vsub.f16 s0, s0, s2 230; CHECK-NEXT: vmov.f16 s4, r2 231; CHECK-NEXT: cmp r0, #0 232; CHECK-NEXT: vsub.f16 s2, s4, s2 233; CHECK-NEXT: vseleq.f16 s0, s0, s4 234; CHECK-NEXT: vseleq.f16 s0, s2, s0 235; CHECK-NEXT: vmov.f16 s2, r3 236; CHECK-NEXT: vadd.f16 s0, s0, s2 237; CHECK-NEXT: vmov r0, s0 238; CHECK-NEXT: bx lr 239 %cmp = icmp eq i32 %arg0, 0 240 %sub.x = fsub nsz half %x, 2.0 241 %sub.y = fsub nsz half %y, 2.0 242 %select0 = select i1 %cmp, half %sub.x, half %y 243 %select1 = select i1 %cmp, half %sub.y, half %select0 244 %add = fadd half %select1, %z 245 ret half %add 246} 247 248define half @fadd_select_fneg_negk_f16(i32 %arg0, half %x, half %y) { 249; CHECK-LABEL: fadd_select_fneg_negk_f16: 250; CHECK: @ %bb.0: 251; CHECK-NEXT: vmov.f16 s0, #4.000000e+00 252; CHECK-NEXT: vmov.f16 s2, r1 253; CHECK-NEXT: cmp r0, #0 254; CHECK-NEXT: vseleq.f16 s0, s2, s0 255; CHECK-NEXT: vmov.f16 s2, r2 256; CHECK-NEXT: vsub.f16 s0, s2, s0 257; CHECK-NEXT: vmov r0, s0 258; CHECK-NEXT: bx lr 259 %cmp = icmp eq i32 %arg0, 0 260 %neg.x = fneg half %x 261 %select = select i1 %cmp, half %neg.x, half -4.0 262 %add = fadd half %select, %y 263 ret half %add 264} 265 266define half @fadd_select_fneg_posk_f16(i32 %arg0, half %x, half %y) { 267; CHECK-LABEL: fadd_select_fneg_posk_f16: 268; CHECK: @ %bb.0: 269; CHECK-NEXT: vmov.f16 s0, #-4.000000e+00 270; CHECK-NEXT: vmov.f16 s2, r1 271; CHECK-NEXT: cmp r0, #0 272; CHECK-NEXT: vseleq.f16 s0, s2, s0 273; CHECK-NEXT: vmov.f16 s2, r2 274; CHECK-NEXT: vsub.f16 s0, s2, s0 275; CHECK-NEXT: vmov r0, s0 276; CHECK-NEXT: bx lr 277 %cmp = icmp eq i32 %arg0, 0 278 %neg.x = fneg half %x 279 %select = select i1 %cmp, half %neg.x, half 4.0 280 %add = fadd half %select, %y 281 ret half %add 282} 283 284define <8 x half> @fadd_vselect_fneg_posk_v8f16(<8 x i32> %arg0, <8 x half> %x, <8 x half> %y) { 285; CHECK-LABEL: fadd_vselect_fneg_posk_v8f16: 286; CHECK: @ %bb.0: 287; CHECK-NEXT: sub sp, sp, #16 288; CHECK-NEXT: vmov d0, r0, r1 289; CHECK-NEXT: add r0, sp, #16 290; CHECK-NEXT: vmov d1, r2, r3 291; CHECK-NEXT: vldrw.u32 q3, [r0] 292; CHECK-NEXT: vcmp.i32 eq, q0, zr 293; CHECK-NEXT: vmov.i8 q0, #0x0 294; CHECK-NEXT: vmov.i8 q1, #0xff 295; CHECK-NEXT: mov r0, sp 296; CHECK-NEXT: vpsel q2, q1, q0 297; CHECK-NEXT: vcmp.i32 eq, q3, zr 298; CHECK-NEXT: vpsel q0, q1, q0 299; CHECK-NEXT: vstrh.32 q2, [r0] 300; CHECK-NEXT: vstrh.32 q0, [r0, #8] 301; CHECK-NEXT: add r1, sp, #32 302; CHECK-NEXT: vldrw.u32 q2, [r0] 303; CHECK-NEXT: vldrw.u32 q0, [r1] 304; CHECK-NEXT: vmov.i16 q1, #0xc400 305; CHECK-NEXT: add r0, sp, #48 306; CHECK-NEXT: vcmp.i16 ne, q2, zr 307; CHECK-NEXT: vpsel q0, q0, q1 308; CHECK-NEXT: vldrw.u32 q1, [r0] 309; CHECK-NEXT: vsub.f16 q0, q1, q0 310; CHECK-NEXT: vmov r0, r1, d0 311; CHECK-NEXT: vmov r2, r3, d1 312; CHECK-NEXT: add sp, sp, #16 313; CHECK-NEXT: bx lr 314 %cmp = icmp eq <8 x i32> %arg0, zeroinitializer 315 %neg.x = fneg <8 x half> %x 316 %select = select <8 x i1> %cmp, <8 x half> %neg.x, <8 x half> <half 4.0, half 4.0, half 4.0, half 4.0, half 4.0, half 4.0, half 4.0, half 4.0> 317 %add = fadd <8 x half> %select, %y 318 ret <8 x half> %add 319} 320