1; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py 2; RUN: llc -mtriple=riscv32 -mattr=+f -verify-machineinstrs < %s \ 3; RUN: | FileCheck -check-prefix=RV32IF %s 4 5define float @select_fcmp_false(float %a, float %b) nounwind { 6; RV32IF-LABEL: select_fcmp_false: 7; RV32IF: # %bb.0: 8; RV32IF-NEXT: mv a0, a1 9; RV32IF-NEXT: ret 10 %1 = fcmp false float %a, %b 11 %2 = select i1 %1, float %a, float %b 12 ret float %2 13} 14 15define float @select_fcmp_oeq(float %a, float %b) nounwind { 16; RV32IF-LABEL: select_fcmp_oeq: 17; RV32IF: # %bb.0: 18; RV32IF-NEXT: fmv.w.x ft1, a1 19; RV32IF-NEXT: fmv.w.x ft0, a0 20; RV32IF-NEXT: feq.s a0, ft0, ft1 21; RV32IF-NEXT: bnez a0, .LBB1_2 22; RV32IF-NEXT: # %bb.1: 23; RV32IF-NEXT: fmv.s ft0, ft1 24; RV32IF-NEXT: .LBB1_2: 25; RV32IF-NEXT: fmv.x.w a0, ft0 26; RV32IF-NEXT: ret 27 %1 = fcmp oeq float %a, %b 28 %2 = select i1 %1, float %a, float %b 29 ret float %2 30} 31 32define float @select_fcmp_ogt(float %a, float %b) nounwind { 33; RV32IF-LABEL: select_fcmp_ogt: 34; RV32IF: # %bb.0: 35; RV32IF-NEXT: fmv.w.x ft0, a0 36; RV32IF-NEXT: fmv.w.x ft1, a1 37; RV32IF-NEXT: flt.s a0, ft1, ft0 38; RV32IF-NEXT: bnez a0, .LBB2_2 39; RV32IF-NEXT: # %bb.1: 40; RV32IF-NEXT: fmv.s ft0, ft1 41; RV32IF-NEXT: .LBB2_2: 42; RV32IF-NEXT: fmv.x.w a0, ft0 43; RV32IF-NEXT: ret 44 %1 = fcmp ogt float %a, %b 45 %2 = select i1 %1, float %a, float %b 46 ret float %2 47} 48 49define float @select_fcmp_oge(float %a, float %b) nounwind { 50; RV32IF-LABEL: select_fcmp_oge: 51; RV32IF: # %bb.0: 52; RV32IF-NEXT: fmv.w.x ft0, a0 53; RV32IF-NEXT: fmv.w.x ft1, a1 54; RV32IF-NEXT: fle.s a0, ft1, ft0 55; RV32IF-NEXT: bnez a0, .LBB3_2 56; RV32IF-NEXT: # %bb.1: 57; RV32IF-NEXT: fmv.s ft0, ft1 58; RV32IF-NEXT: .LBB3_2: 59; RV32IF-NEXT: fmv.x.w a0, ft0 60; RV32IF-NEXT: ret 61 %1 = fcmp oge float %a, %b 62 %2 = select i1 %1, float %a, float %b 63 ret float %2 64} 65 66define float @select_fcmp_olt(float %a, float %b) nounwind { 67; RV32IF-LABEL: select_fcmp_olt: 68; RV32IF: # %bb.0: 69; RV32IF-NEXT: fmv.w.x ft1, a1 70; RV32IF-NEXT: fmv.w.x ft0, a0 71; RV32IF-NEXT: flt.s a0, ft0, ft1 72; RV32IF-NEXT: bnez a0, .LBB4_2 73; RV32IF-NEXT: # %bb.1: 74; RV32IF-NEXT: fmv.s ft0, ft1 75; RV32IF-NEXT: .LBB4_2: 76; RV32IF-NEXT: fmv.x.w a0, ft0 77; RV32IF-NEXT: ret 78 %1 = fcmp olt float %a, %b 79 %2 = select i1 %1, float %a, float %b 80 ret float %2 81} 82 83define float @select_fcmp_ole(float %a, float %b) nounwind { 84; RV32IF-LABEL: select_fcmp_ole: 85; RV32IF: # %bb.0: 86; RV32IF-NEXT: fmv.w.x ft1, a1 87; RV32IF-NEXT: fmv.w.x ft0, a0 88; RV32IF-NEXT: fle.s a0, ft0, ft1 89; RV32IF-NEXT: bnez a0, .LBB5_2 90; RV32IF-NEXT: # %bb.1: 91; RV32IF-NEXT: fmv.s ft0, ft1 92; RV32IF-NEXT: .LBB5_2: 93; RV32IF-NEXT: fmv.x.w a0, ft0 94; RV32IF-NEXT: ret 95 %1 = fcmp ole float %a, %b 96 %2 = select i1 %1, float %a, float %b 97 ret float %2 98} 99 100define float @select_fcmp_one(float %a, float %b) nounwind { 101; TODO: feq.s+sltiu+bne sequence could be optimised 102; RV32IF-LABEL: select_fcmp_one: 103; RV32IF: # %bb.0: 104; RV32IF-NEXT: fmv.w.x ft0, a0 105; RV32IF-NEXT: fmv.w.x ft1, a1 106; RV32IF-NEXT: feq.s a0, ft1, ft1 107; RV32IF-NEXT: feq.s a1, ft0, ft0 108; RV32IF-NEXT: and a0, a1, a0 109; RV32IF-NEXT: feq.s a1, ft0, ft1 110; RV32IF-NEXT: not a1, a1 111; RV32IF-NEXT: seqz a0, a0 112; RV32IF-NEXT: xori a0, a0, 1 113; RV32IF-NEXT: and a0, a1, a0 114; RV32IF-NEXT: bnez a0, .LBB6_2 115; RV32IF-NEXT: # %bb.1: 116; RV32IF-NEXT: fmv.s ft0, ft1 117; RV32IF-NEXT: .LBB6_2: 118; RV32IF-NEXT: fmv.x.w a0, ft0 119; RV32IF-NEXT: ret 120 %1 = fcmp one float %a, %b 121 %2 = select i1 %1, float %a, float %b 122 ret float %2 123} 124 125define float @select_fcmp_ord(float %a, float %b) nounwind { 126; RV32IF-LABEL: select_fcmp_ord: 127; RV32IF: # %bb.0: 128; RV32IF-NEXT: fmv.w.x ft0, a0 129; RV32IF-NEXT: fmv.w.x ft1, a1 130; RV32IF-NEXT: feq.s a0, ft1, ft1 131; RV32IF-NEXT: feq.s a1, ft0, ft0 132; RV32IF-NEXT: and a0, a1, a0 133; RV32IF-NEXT: seqz a0, a0 134; RV32IF-NEXT: xori a0, a0, 1 135; RV32IF-NEXT: bnez a0, .LBB7_2 136; RV32IF-NEXT: # %bb.1: 137; RV32IF-NEXT: fmv.s ft0, ft1 138; RV32IF-NEXT: .LBB7_2: 139; RV32IF-NEXT: fmv.x.w a0, ft0 140; RV32IF-NEXT: ret 141 %1 = fcmp ord float %a, %b 142 %2 = select i1 %1, float %a, float %b 143 ret float %2 144} 145 146define float @select_fcmp_ueq(float %a, float %b) nounwind { 147; RV32IF-LABEL: select_fcmp_ueq: 148; RV32IF: # %bb.0: 149; RV32IF-NEXT: fmv.w.x ft0, a0 150; RV32IF-NEXT: fmv.w.x ft1, a1 151; RV32IF-NEXT: feq.s a0, ft1, ft1 152; RV32IF-NEXT: feq.s a1, ft0, ft0 153; RV32IF-NEXT: and a0, a1, a0 154; RV32IF-NEXT: seqz a0, a0 155; RV32IF-NEXT: feq.s a1, ft0, ft1 156; RV32IF-NEXT: or a0, a1, a0 157; RV32IF-NEXT: bnez a0, .LBB8_2 158; RV32IF-NEXT: # %bb.1: 159; RV32IF-NEXT: fmv.s ft0, ft1 160; RV32IF-NEXT: .LBB8_2: 161; RV32IF-NEXT: fmv.x.w a0, ft0 162; RV32IF-NEXT: ret 163 %1 = fcmp ueq float %a, %b 164 %2 = select i1 %1, float %a, float %b 165 ret float %2 166} 167 168define float @select_fcmp_ugt(float %a, float %b) nounwind { 169; RV32IF-LABEL: select_fcmp_ugt: 170; RV32IF: # %bb.0: 171; RV32IF-NEXT: fmv.w.x ft1, a1 172; RV32IF-NEXT: fmv.w.x ft0, a0 173; RV32IF-NEXT: fle.s a0, ft0, ft1 174; RV32IF-NEXT: xori a0, a0, 1 175; RV32IF-NEXT: bnez a0, .LBB9_2 176; RV32IF-NEXT: # %bb.1: 177; RV32IF-NEXT: fmv.s ft0, ft1 178; RV32IF-NEXT: .LBB9_2: 179; RV32IF-NEXT: fmv.x.w a0, ft0 180; RV32IF-NEXT: ret 181 %1 = fcmp ugt float %a, %b 182 %2 = select i1 %1, float %a, float %b 183 ret float %2 184} 185 186define float @select_fcmp_uge(float %a, float %b) nounwind { 187; RV32IF-LABEL: select_fcmp_uge: 188; RV32IF: # %bb.0: 189; RV32IF-NEXT: fmv.w.x ft1, a1 190; RV32IF-NEXT: fmv.w.x ft0, a0 191; RV32IF-NEXT: flt.s a0, ft0, ft1 192; RV32IF-NEXT: xori a0, a0, 1 193; RV32IF-NEXT: bnez a0, .LBB10_2 194; RV32IF-NEXT: # %bb.1: 195; RV32IF-NEXT: fmv.s ft0, ft1 196; RV32IF-NEXT: .LBB10_2: 197; RV32IF-NEXT: fmv.x.w a0, ft0 198; RV32IF-NEXT: ret 199 %1 = fcmp uge float %a, %b 200 %2 = select i1 %1, float %a, float %b 201 ret float %2 202} 203 204define float @select_fcmp_ult(float %a, float %b) nounwind { 205; RV32IF-LABEL: select_fcmp_ult: 206; RV32IF: # %bb.0: 207; RV32IF-NEXT: fmv.w.x ft0, a0 208; RV32IF-NEXT: fmv.w.x ft1, a1 209; RV32IF-NEXT: fle.s a0, ft1, ft0 210; RV32IF-NEXT: xori a0, a0, 1 211; RV32IF-NEXT: bnez a0, .LBB11_2 212; RV32IF-NEXT: # %bb.1: 213; RV32IF-NEXT: fmv.s ft0, ft1 214; RV32IF-NEXT: .LBB11_2: 215; RV32IF-NEXT: fmv.x.w a0, ft0 216; RV32IF-NEXT: ret 217 %1 = fcmp ult float %a, %b 218 %2 = select i1 %1, float %a, float %b 219 ret float %2 220} 221 222define float @select_fcmp_ule(float %a, float %b) nounwind { 223; RV32IF-LABEL: select_fcmp_ule: 224; RV32IF: # %bb.0: 225; RV32IF-NEXT: fmv.w.x ft0, a0 226; RV32IF-NEXT: fmv.w.x ft1, a1 227; RV32IF-NEXT: flt.s a0, ft1, ft0 228; RV32IF-NEXT: xori a0, a0, 1 229; RV32IF-NEXT: bnez a0, .LBB12_2 230; RV32IF-NEXT: # %bb.1: 231; RV32IF-NEXT: fmv.s ft0, ft1 232; RV32IF-NEXT: .LBB12_2: 233; RV32IF-NEXT: fmv.x.w a0, ft0 234; RV32IF-NEXT: ret 235 %1 = fcmp ule float %a, %b 236 %2 = select i1 %1, float %a, float %b 237 ret float %2 238} 239 240define float @select_fcmp_une(float %a, float %b) nounwind { 241; RV32IF-LABEL: select_fcmp_une: 242; RV32IF: # %bb.0: 243; RV32IF-NEXT: fmv.w.x ft1, a1 244; RV32IF-NEXT: fmv.w.x ft0, a0 245; RV32IF-NEXT: feq.s a0, ft0, ft1 246; RV32IF-NEXT: xori a0, a0, 1 247; RV32IF-NEXT: bnez a0, .LBB13_2 248; RV32IF-NEXT: # %bb.1: 249; RV32IF-NEXT: fmv.s ft0, ft1 250; RV32IF-NEXT: .LBB13_2: 251; RV32IF-NEXT: fmv.x.w a0, ft0 252; RV32IF-NEXT: ret 253 %1 = fcmp une float %a, %b 254 %2 = select i1 %1, float %a, float %b 255 ret float %2 256} 257 258define float @select_fcmp_uno(float %a, float %b) nounwind { 259; TODO: sltiu+bne could be optimized 260; RV32IF-LABEL: select_fcmp_uno: 261; RV32IF: # %bb.0: 262; RV32IF-NEXT: fmv.w.x ft0, a0 263; RV32IF-NEXT: fmv.w.x ft1, a1 264; RV32IF-NEXT: feq.s a0, ft1, ft1 265; RV32IF-NEXT: feq.s a1, ft0, ft0 266; RV32IF-NEXT: and a0, a1, a0 267; RV32IF-NEXT: seqz a0, a0 268; RV32IF-NEXT: bnez a0, .LBB14_2 269; RV32IF-NEXT: # %bb.1: 270; RV32IF-NEXT: fmv.s ft0, ft1 271; RV32IF-NEXT: .LBB14_2: 272; RV32IF-NEXT: fmv.x.w a0, ft0 273; RV32IF-NEXT: ret 274 %1 = fcmp uno float %a, %b 275 %2 = select i1 %1, float %a, float %b 276 ret float %2 277} 278 279define float @select_fcmp_true(float %a, float %b) nounwind { 280; RV32IF-LABEL: select_fcmp_true: 281; RV32IF: # %bb.0: 282; RV32IF-NEXT: ret 283 %1 = fcmp true float %a, %b 284 %2 = select i1 %1, float %a, float %b 285 ret float %2 286} 287 288; Ensure that ISel succeeds for a select+fcmp that has an i32 result type. 289define i32 @i32_select_fcmp_oeq(float %a, float %b, i32 %c, i32 %d) nounwind { 290; RV32IF-LABEL: i32_select_fcmp_oeq: 291; RV32IF: # %bb.0: 292; RV32IF-NEXT: fmv.w.x ft0, a1 293; RV32IF-NEXT: fmv.w.x ft1, a0 294; RV32IF-NEXT: feq.s a0, ft1, ft0 295; RV32IF-NEXT: bnez a0, .LBB16_2 296; RV32IF-NEXT: # %bb.1: 297; RV32IF-NEXT: mv a2, a3 298; RV32IF-NEXT: .LBB16_2: 299; RV32IF-NEXT: mv a0, a2 300; RV32IF-NEXT: ret 301 %1 = fcmp oeq float %a, %b 302 %2 = select i1 %1, i32 %c, i32 %d 303 ret i32 %2 304} 305