1; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py 2; RUN: llc -mtriple=riscv32 -mattr=+d -verify-machineinstrs < %s \ 3; RUN: | FileCheck -check-prefix=RV32IFD %s 4 5define double @select_fcmp_false(double %a, double %b) nounwind { 6; RV32IFD-LABEL: select_fcmp_false: 7; RV32IFD: # %bb.0: 8; RV32IFD-NEXT: mv a0, a2 9; RV32IFD-NEXT: mv a1, a3 10; RV32IFD-NEXT: ret 11 %1 = fcmp false double %a, %b 12 %2 = select i1 %1, double %a, double %b 13 ret double %2 14} 15 16define double @select_fcmp_oeq(double %a, double %b) nounwind { 17; RV32IFD-LABEL: select_fcmp_oeq: 18; RV32IFD: # %bb.0: 19; RV32IFD-NEXT: addi sp, sp, -16 20; RV32IFD-NEXT: sw a2, 8(sp) 21; RV32IFD-NEXT: sw a3, 12(sp) 22; RV32IFD-NEXT: fld ft0, 8(sp) 23; RV32IFD-NEXT: sw a0, 8(sp) 24; RV32IFD-NEXT: sw a1, 12(sp) 25; RV32IFD-NEXT: fld ft1, 8(sp) 26; RV32IFD-NEXT: feq.d a0, ft1, ft0 27; RV32IFD-NEXT: bnez a0, .LBB1_2 28; RV32IFD-NEXT: # %bb.1: 29; RV32IFD-NEXT: fmv.d ft1, ft0 30; RV32IFD-NEXT: .LBB1_2: 31; RV32IFD-NEXT: fsd ft1, 8(sp) 32; RV32IFD-NEXT: lw a0, 8(sp) 33; RV32IFD-NEXT: lw a1, 12(sp) 34; RV32IFD-NEXT: addi sp, sp, 16 35; RV32IFD-NEXT: ret 36 %1 = fcmp oeq double %a, %b 37 %2 = select i1 %1, double %a, double %b 38 ret double %2 39} 40 41define double @select_fcmp_ogt(double %a, double %b) nounwind { 42; RV32IFD-LABEL: select_fcmp_ogt: 43; RV32IFD: # %bb.0: 44; RV32IFD-NEXT: addi sp, sp, -16 45; RV32IFD-NEXT: sw a0, 8(sp) 46; RV32IFD-NEXT: sw a1, 12(sp) 47; RV32IFD-NEXT: fld ft0, 8(sp) 48; RV32IFD-NEXT: sw a2, 8(sp) 49; RV32IFD-NEXT: sw a3, 12(sp) 50; RV32IFD-NEXT: fld ft1, 8(sp) 51; RV32IFD-NEXT: flt.d a0, ft1, ft0 52; RV32IFD-NEXT: bnez a0, .LBB2_2 53; RV32IFD-NEXT: # %bb.1: 54; RV32IFD-NEXT: fmv.d ft0, ft1 55; RV32IFD-NEXT: .LBB2_2: 56; RV32IFD-NEXT: fsd ft0, 8(sp) 57; RV32IFD-NEXT: lw a0, 8(sp) 58; RV32IFD-NEXT: lw a1, 12(sp) 59; RV32IFD-NEXT: addi sp, sp, 16 60; RV32IFD-NEXT: ret 61 %1 = fcmp ogt double %a, %b 62 %2 = select i1 %1, double %a, double %b 63 ret double %2 64} 65 66define double @select_fcmp_oge(double %a, double %b) nounwind { 67; RV32IFD-LABEL: select_fcmp_oge: 68; RV32IFD: # %bb.0: 69; RV32IFD-NEXT: addi sp, sp, -16 70; RV32IFD-NEXT: sw a0, 8(sp) 71; RV32IFD-NEXT: sw a1, 12(sp) 72; RV32IFD-NEXT: fld ft0, 8(sp) 73; RV32IFD-NEXT: sw a2, 8(sp) 74; RV32IFD-NEXT: sw a3, 12(sp) 75; RV32IFD-NEXT: fld ft1, 8(sp) 76; RV32IFD-NEXT: fle.d a0, ft1, ft0 77; RV32IFD-NEXT: bnez a0, .LBB3_2 78; RV32IFD-NEXT: # %bb.1: 79; RV32IFD-NEXT: fmv.d ft0, ft1 80; RV32IFD-NEXT: .LBB3_2: 81; RV32IFD-NEXT: fsd ft0, 8(sp) 82; RV32IFD-NEXT: lw a0, 8(sp) 83; RV32IFD-NEXT: lw a1, 12(sp) 84; RV32IFD-NEXT: addi sp, sp, 16 85; RV32IFD-NEXT: ret 86 %1 = fcmp oge double %a, %b 87 %2 = select i1 %1, double %a, double %b 88 ret double %2 89} 90 91define double @select_fcmp_olt(double %a, double %b) nounwind { 92; RV32IFD-LABEL: select_fcmp_olt: 93; RV32IFD: # %bb.0: 94; RV32IFD-NEXT: addi sp, sp, -16 95; RV32IFD-NEXT: sw a2, 8(sp) 96; RV32IFD-NEXT: sw a3, 12(sp) 97; RV32IFD-NEXT: fld ft0, 8(sp) 98; RV32IFD-NEXT: sw a0, 8(sp) 99; RV32IFD-NEXT: sw a1, 12(sp) 100; RV32IFD-NEXT: fld ft1, 8(sp) 101; RV32IFD-NEXT: flt.d a0, ft1, ft0 102; RV32IFD-NEXT: bnez a0, .LBB4_2 103; RV32IFD-NEXT: # %bb.1: 104; RV32IFD-NEXT: fmv.d ft1, ft0 105; RV32IFD-NEXT: .LBB4_2: 106; RV32IFD-NEXT: fsd ft1, 8(sp) 107; RV32IFD-NEXT: lw a0, 8(sp) 108; RV32IFD-NEXT: lw a1, 12(sp) 109; RV32IFD-NEXT: addi sp, sp, 16 110; RV32IFD-NEXT: ret 111 %1 = fcmp olt double %a, %b 112 %2 = select i1 %1, double %a, double %b 113 ret double %2 114} 115 116define double @select_fcmp_ole(double %a, double %b) nounwind { 117; RV32IFD-LABEL: select_fcmp_ole: 118; RV32IFD: # %bb.0: 119; RV32IFD-NEXT: addi sp, sp, -16 120; RV32IFD-NEXT: sw a2, 8(sp) 121; RV32IFD-NEXT: sw a3, 12(sp) 122; RV32IFD-NEXT: fld ft0, 8(sp) 123; RV32IFD-NEXT: sw a0, 8(sp) 124; RV32IFD-NEXT: sw a1, 12(sp) 125; RV32IFD-NEXT: fld ft1, 8(sp) 126; RV32IFD-NEXT: fle.d a0, ft1, ft0 127; RV32IFD-NEXT: bnez a0, .LBB5_2 128; RV32IFD-NEXT: # %bb.1: 129; RV32IFD-NEXT: fmv.d ft1, ft0 130; RV32IFD-NEXT: .LBB5_2: 131; RV32IFD-NEXT: fsd ft1, 8(sp) 132; RV32IFD-NEXT: lw a0, 8(sp) 133; RV32IFD-NEXT: lw a1, 12(sp) 134; RV32IFD-NEXT: addi sp, sp, 16 135; RV32IFD-NEXT: ret 136 %1 = fcmp ole double %a, %b 137 %2 = select i1 %1, double %a, double %b 138 ret double %2 139} 140 141define double @select_fcmp_one(double %a, double %b) nounwind { 142; TODO: feq.s+sltiu+bne sequence could be optimised 143; RV32IFD-LABEL: select_fcmp_one: 144; RV32IFD: # %bb.0: 145; RV32IFD-NEXT: addi sp, sp, -16 146; RV32IFD-NEXT: sw a0, 8(sp) 147; RV32IFD-NEXT: sw a1, 12(sp) 148; RV32IFD-NEXT: fld ft0, 8(sp) 149; RV32IFD-NEXT: sw a2, 8(sp) 150; RV32IFD-NEXT: sw a3, 12(sp) 151; RV32IFD-NEXT: fld ft1, 8(sp) 152; RV32IFD-NEXT: feq.d a0, ft1, ft1 153; RV32IFD-NEXT: feq.d a1, ft0, ft0 154; RV32IFD-NEXT: and a0, a1, a0 155; RV32IFD-NEXT: feq.d a1, ft0, ft1 156; RV32IFD-NEXT: not a1, a1 157; RV32IFD-NEXT: seqz a0, a0 158; RV32IFD-NEXT: xori a0, a0, 1 159; RV32IFD-NEXT: and a0, a1, a0 160; RV32IFD-NEXT: bnez a0, .LBB6_2 161; RV32IFD-NEXT: # %bb.1: 162; RV32IFD-NEXT: fmv.d ft0, ft1 163; RV32IFD-NEXT: .LBB6_2: 164; RV32IFD-NEXT: fsd ft0, 8(sp) 165; RV32IFD-NEXT: lw a0, 8(sp) 166; RV32IFD-NEXT: lw a1, 12(sp) 167; RV32IFD-NEXT: addi sp, sp, 16 168; RV32IFD-NEXT: ret 169 %1 = fcmp one double %a, %b 170 %2 = select i1 %1, double %a, double %b 171 ret double %2 172} 173 174define double @select_fcmp_ord(double %a, double %b) nounwind { 175; RV32IFD-LABEL: select_fcmp_ord: 176; RV32IFD: # %bb.0: 177; RV32IFD-NEXT: addi sp, sp, -16 178; RV32IFD-NEXT: sw a0, 8(sp) 179; RV32IFD-NEXT: sw a1, 12(sp) 180; RV32IFD-NEXT: fld ft0, 8(sp) 181; RV32IFD-NEXT: sw a2, 8(sp) 182; RV32IFD-NEXT: sw a3, 12(sp) 183; RV32IFD-NEXT: fld ft1, 8(sp) 184; RV32IFD-NEXT: feq.d a0, ft1, ft1 185; RV32IFD-NEXT: feq.d a1, ft0, ft0 186; RV32IFD-NEXT: and a0, a1, a0 187; RV32IFD-NEXT: seqz a0, a0 188; RV32IFD-NEXT: xori a0, a0, 1 189; RV32IFD-NEXT: bnez a0, .LBB7_2 190; RV32IFD-NEXT: # %bb.1: 191; RV32IFD-NEXT: fmv.d ft0, ft1 192; RV32IFD-NEXT: .LBB7_2: 193; RV32IFD-NEXT: fsd ft0, 8(sp) 194; RV32IFD-NEXT: lw a0, 8(sp) 195; RV32IFD-NEXT: lw a1, 12(sp) 196; RV32IFD-NEXT: addi sp, sp, 16 197; RV32IFD-NEXT: ret 198 %1 = fcmp ord double %a, %b 199 %2 = select i1 %1, double %a, double %b 200 ret double %2 201} 202 203define double @select_fcmp_ueq(double %a, double %b) nounwind { 204; RV32IFD-LABEL: select_fcmp_ueq: 205; RV32IFD: # %bb.0: 206; RV32IFD-NEXT: addi sp, sp, -16 207; RV32IFD-NEXT: sw a0, 8(sp) 208; RV32IFD-NEXT: sw a1, 12(sp) 209; RV32IFD-NEXT: fld ft0, 8(sp) 210; RV32IFD-NEXT: sw a2, 8(sp) 211; RV32IFD-NEXT: sw a3, 12(sp) 212; RV32IFD-NEXT: fld ft1, 8(sp) 213; RV32IFD-NEXT: feq.d a0, ft1, ft1 214; RV32IFD-NEXT: feq.d a1, ft0, ft0 215; RV32IFD-NEXT: and a0, a1, a0 216; RV32IFD-NEXT: seqz a0, a0 217; RV32IFD-NEXT: feq.d a1, ft0, ft1 218; RV32IFD-NEXT: or a0, a1, a0 219; RV32IFD-NEXT: bnez a0, .LBB8_2 220; RV32IFD-NEXT: # %bb.1: 221; RV32IFD-NEXT: fmv.d ft0, ft1 222; RV32IFD-NEXT: .LBB8_2: 223; RV32IFD-NEXT: fsd ft0, 8(sp) 224; RV32IFD-NEXT: lw a0, 8(sp) 225; RV32IFD-NEXT: lw a1, 12(sp) 226; RV32IFD-NEXT: addi sp, sp, 16 227; RV32IFD-NEXT: ret 228 %1 = fcmp ueq double %a, %b 229 %2 = select i1 %1, double %a, double %b 230 ret double %2 231} 232 233define double @select_fcmp_ugt(double %a, double %b) nounwind { 234; RV32IFD-LABEL: select_fcmp_ugt: 235; RV32IFD: # %bb.0: 236; RV32IFD-NEXT: addi sp, sp, -16 237; RV32IFD-NEXT: sw a2, 8(sp) 238; RV32IFD-NEXT: sw a3, 12(sp) 239; RV32IFD-NEXT: fld ft0, 8(sp) 240; RV32IFD-NEXT: sw a0, 8(sp) 241; RV32IFD-NEXT: sw a1, 12(sp) 242; RV32IFD-NEXT: fld ft1, 8(sp) 243; RV32IFD-NEXT: fle.d a0, ft1, ft0 244; RV32IFD-NEXT: xori a0, a0, 1 245; RV32IFD-NEXT: bnez a0, .LBB9_2 246; RV32IFD-NEXT: # %bb.1: 247; RV32IFD-NEXT: fmv.d ft1, ft0 248; RV32IFD-NEXT: .LBB9_2: 249; RV32IFD-NEXT: fsd ft1, 8(sp) 250; RV32IFD-NEXT: lw a0, 8(sp) 251; RV32IFD-NEXT: lw a1, 12(sp) 252; RV32IFD-NEXT: addi sp, sp, 16 253; RV32IFD-NEXT: ret 254 %1 = fcmp ugt double %a, %b 255 %2 = select i1 %1, double %a, double %b 256 ret double %2 257} 258 259define double @select_fcmp_uge(double %a, double %b) nounwind { 260; RV32IFD-LABEL: select_fcmp_uge: 261; RV32IFD: # %bb.0: 262; RV32IFD-NEXT: addi sp, sp, -16 263; RV32IFD-NEXT: sw a2, 8(sp) 264; RV32IFD-NEXT: sw a3, 12(sp) 265; RV32IFD-NEXT: fld ft0, 8(sp) 266; RV32IFD-NEXT: sw a0, 8(sp) 267; RV32IFD-NEXT: sw a1, 12(sp) 268; RV32IFD-NEXT: fld ft1, 8(sp) 269; RV32IFD-NEXT: flt.d a0, ft1, ft0 270; RV32IFD-NEXT: xori a0, a0, 1 271; RV32IFD-NEXT: bnez a0, .LBB10_2 272; RV32IFD-NEXT: # %bb.1: 273; RV32IFD-NEXT: fmv.d ft1, ft0 274; RV32IFD-NEXT: .LBB10_2: 275; RV32IFD-NEXT: fsd ft1, 8(sp) 276; RV32IFD-NEXT: lw a0, 8(sp) 277; RV32IFD-NEXT: lw a1, 12(sp) 278; RV32IFD-NEXT: addi sp, sp, 16 279; RV32IFD-NEXT: ret 280 %1 = fcmp uge double %a, %b 281 %2 = select i1 %1, double %a, double %b 282 ret double %2 283} 284 285define double @select_fcmp_ult(double %a, double %b) nounwind { 286; RV32IFD-LABEL: select_fcmp_ult: 287; RV32IFD: # %bb.0: 288; RV32IFD-NEXT: addi sp, sp, -16 289; RV32IFD-NEXT: sw a0, 8(sp) 290; RV32IFD-NEXT: sw a1, 12(sp) 291; RV32IFD-NEXT: fld ft0, 8(sp) 292; RV32IFD-NEXT: sw a2, 8(sp) 293; RV32IFD-NEXT: sw a3, 12(sp) 294; RV32IFD-NEXT: fld ft1, 8(sp) 295; RV32IFD-NEXT: fle.d a0, ft1, ft0 296; RV32IFD-NEXT: xori a0, a0, 1 297; RV32IFD-NEXT: bnez a0, .LBB11_2 298; RV32IFD-NEXT: # %bb.1: 299; RV32IFD-NEXT: fmv.d ft0, ft1 300; RV32IFD-NEXT: .LBB11_2: 301; RV32IFD-NEXT: fsd ft0, 8(sp) 302; RV32IFD-NEXT: lw a0, 8(sp) 303; RV32IFD-NEXT: lw a1, 12(sp) 304; RV32IFD-NEXT: addi sp, sp, 16 305; RV32IFD-NEXT: ret 306 %1 = fcmp ult double %a, %b 307 %2 = select i1 %1, double %a, double %b 308 ret double %2 309} 310 311define double @select_fcmp_ule(double %a, double %b) nounwind { 312; RV32IFD-LABEL: select_fcmp_ule: 313; RV32IFD: # %bb.0: 314; RV32IFD-NEXT: addi sp, sp, -16 315; RV32IFD-NEXT: sw a0, 8(sp) 316; RV32IFD-NEXT: sw a1, 12(sp) 317; RV32IFD-NEXT: fld ft0, 8(sp) 318; RV32IFD-NEXT: sw a2, 8(sp) 319; RV32IFD-NEXT: sw a3, 12(sp) 320; RV32IFD-NEXT: fld ft1, 8(sp) 321; RV32IFD-NEXT: flt.d a0, ft1, ft0 322; RV32IFD-NEXT: xori a0, a0, 1 323; RV32IFD-NEXT: bnez a0, .LBB12_2 324; RV32IFD-NEXT: # %bb.1: 325; RV32IFD-NEXT: fmv.d ft0, ft1 326; RV32IFD-NEXT: .LBB12_2: 327; RV32IFD-NEXT: fsd ft0, 8(sp) 328; RV32IFD-NEXT: lw a0, 8(sp) 329; RV32IFD-NEXT: lw a1, 12(sp) 330; RV32IFD-NEXT: addi sp, sp, 16 331; RV32IFD-NEXT: ret 332 %1 = fcmp ule double %a, %b 333 %2 = select i1 %1, double %a, double %b 334 ret double %2 335} 336 337define double @select_fcmp_une(double %a, double %b) nounwind { 338; RV32IFD-LABEL: select_fcmp_une: 339; RV32IFD: # %bb.0: 340; RV32IFD-NEXT: addi sp, sp, -16 341; RV32IFD-NEXT: sw a2, 8(sp) 342; RV32IFD-NEXT: sw a3, 12(sp) 343; RV32IFD-NEXT: fld ft0, 8(sp) 344; RV32IFD-NEXT: sw a0, 8(sp) 345; RV32IFD-NEXT: sw a1, 12(sp) 346; RV32IFD-NEXT: fld ft1, 8(sp) 347; RV32IFD-NEXT: feq.d a0, ft1, ft0 348; RV32IFD-NEXT: xori a0, a0, 1 349; RV32IFD-NEXT: bnez a0, .LBB13_2 350; RV32IFD-NEXT: # %bb.1: 351; RV32IFD-NEXT: fmv.d ft1, ft0 352; RV32IFD-NEXT: .LBB13_2: 353; RV32IFD-NEXT: fsd ft1, 8(sp) 354; RV32IFD-NEXT: lw a0, 8(sp) 355; RV32IFD-NEXT: lw a1, 12(sp) 356; RV32IFD-NEXT: addi sp, sp, 16 357; RV32IFD-NEXT: ret 358 %1 = fcmp une double %a, %b 359 %2 = select i1 %1, double %a, double %b 360 ret double %2 361} 362 363define double @select_fcmp_uno(double %a, double %b) nounwind { 364; TODO: sltiu+bne could be optimized 365; RV32IFD-LABEL: select_fcmp_uno: 366; RV32IFD: # %bb.0: 367; RV32IFD-NEXT: addi sp, sp, -16 368; RV32IFD-NEXT: sw a0, 8(sp) 369; RV32IFD-NEXT: sw a1, 12(sp) 370; RV32IFD-NEXT: fld ft0, 8(sp) 371; RV32IFD-NEXT: sw a2, 8(sp) 372; RV32IFD-NEXT: sw a3, 12(sp) 373; RV32IFD-NEXT: fld ft1, 8(sp) 374; RV32IFD-NEXT: feq.d a0, ft1, ft1 375; RV32IFD-NEXT: feq.d a1, ft0, ft0 376; RV32IFD-NEXT: and a0, a1, a0 377; RV32IFD-NEXT: seqz a0, a0 378; RV32IFD-NEXT: bnez a0, .LBB14_2 379; RV32IFD-NEXT: # %bb.1: 380; RV32IFD-NEXT: fmv.d ft0, ft1 381; RV32IFD-NEXT: .LBB14_2: 382; RV32IFD-NEXT: fsd ft0, 8(sp) 383; RV32IFD-NEXT: lw a0, 8(sp) 384; RV32IFD-NEXT: lw a1, 12(sp) 385; RV32IFD-NEXT: addi sp, sp, 16 386; RV32IFD-NEXT: ret 387 %1 = fcmp uno double %a, %b 388 %2 = select i1 %1, double %a, double %b 389 ret double %2 390} 391 392define double @select_fcmp_true(double %a, double %b) nounwind { 393; RV32IFD-LABEL: select_fcmp_true: 394; RV32IFD: # %bb.0: 395; RV32IFD-NEXT: ret 396 %1 = fcmp true double %a, %b 397 %2 = select i1 %1, double %a, double %b 398 ret double %2 399} 400 401; Ensure that ISel succeeds for a select+fcmp that has an i32 result type. 402define i32 @i32_select_fcmp_oeq(double %a, double %b, i32 %c, i32 %d) nounwind { 403; RV32IFD-LABEL: i32_select_fcmp_oeq: 404; RV32IFD: # %bb.0: 405; RV32IFD-NEXT: addi sp, sp, -16 406; RV32IFD-NEXT: sw a2, 8(sp) 407; RV32IFD-NEXT: sw a3, 12(sp) 408; RV32IFD-NEXT: fld ft0, 8(sp) 409; RV32IFD-NEXT: sw a0, 8(sp) 410; RV32IFD-NEXT: sw a1, 12(sp) 411; RV32IFD-NEXT: fld ft1, 8(sp) 412; RV32IFD-NEXT: feq.d a0, ft1, ft0 413; RV32IFD-NEXT: bnez a0, .LBB16_2 414; RV32IFD-NEXT: # %bb.1: 415; RV32IFD-NEXT: mv a4, a5 416; RV32IFD-NEXT: .LBB16_2: 417; RV32IFD-NEXT: mv a0, a4 418; RV32IFD-NEXT: addi sp, sp, 16 419; RV32IFD-NEXT: ret 420 %1 = fcmp oeq double %a, %b 421 %2 = select i1 %1, i32 %c, i32 %d 422 ret i32 %2 423} 424