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; RUN: llc -mtriple=riscv64 -mattr=+f -verify-machineinstrs < %s \ 5; RUN: | FileCheck -check-prefix=RV64IF %s 6 7declare void @abort() 8declare void @exit(i32) 9declare float @dummy(float) 10 11define void @br_fcmp_false(float %a, float %b) nounwind { 12; RV32IF-LABEL: br_fcmp_false: 13; RV32IF: # %bb.0: 14; RV32IF-NEXT: addi sp, sp, -16 15; RV32IF-NEXT: sw ra, 12(sp) 16; RV32IF-NEXT: addi a0, zero, 1 17; RV32IF-NEXT: bnez a0, .LBB0_2 18; RV32IF-NEXT: # %bb.1: # %if.then 19; RV32IF-NEXT: lw ra, 12(sp) 20; RV32IF-NEXT: addi sp, sp, 16 21; RV32IF-NEXT: ret 22; RV32IF-NEXT: .LBB0_2: # %if.else 23; RV32IF-NEXT: call abort 24; 25; RV64IF-LABEL: br_fcmp_false: 26; RV64IF: # %bb.0: 27; RV64IF-NEXT: addi sp, sp, -16 28; RV64IF-NEXT: sd ra, 8(sp) 29; RV64IF-NEXT: addi a0, zero, 1 30; RV64IF-NEXT: bnez a0, .LBB0_2 31; RV64IF-NEXT: # %bb.1: # %if.then 32; RV64IF-NEXT: ld ra, 8(sp) 33; RV64IF-NEXT: addi sp, sp, 16 34; RV64IF-NEXT: ret 35; RV64IF-NEXT: .LBB0_2: # %if.else 36; RV64IF-NEXT: call abort 37 %1 = fcmp false float %a, %b 38 br i1 %1, label %if.then, label %if.else 39if.then: 40 ret void 41if.else: 42 tail call void @abort() 43 unreachable 44} 45 46define void @br_fcmp_oeq(float %a, float %b) nounwind { 47; RV32IF-LABEL: br_fcmp_oeq: 48; RV32IF: # %bb.0: 49; RV32IF-NEXT: addi sp, sp, -16 50; RV32IF-NEXT: sw ra, 12(sp) 51; RV32IF-NEXT: fmv.w.x ft0, a1 52; RV32IF-NEXT: fmv.w.x ft1, a0 53; RV32IF-NEXT: feq.s a0, ft1, ft0 54; RV32IF-NEXT: bnez a0, .LBB1_2 55; RV32IF-NEXT: # %bb.1: # %if.else 56; RV32IF-NEXT: lw ra, 12(sp) 57; RV32IF-NEXT: addi sp, sp, 16 58; RV32IF-NEXT: ret 59; RV32IF-NEXT: .LBB1_2: # %if.then 60; RV32IF-NEXT: call abort 61; 62; RV64IF-LABEL: br_fcmp_oeq: 63; RV64IF: # %bb.0: 64; RV64IF-NEXT: addi sp, sp, -16 65; RV64IF-NEXT: sd ra, 8(sp) 66; RV64IF-NEXT: fmv.w.x ft0, a1 67; RV64IF-NEXT: fmv.w.x ft1, a0 68; RV64IF-NEXT: feq.s a0, ft1, ft0 69; RV64IF-NEXT: bnez a0, .LBB1_2 70; RV64IF-NEXT: # %bb.1: # %if.else 71; RV64IF-NEXT: ld ra, 8(sp) 72; RV64IF-NEXT: addi sp, sp, 16 73; RV64IF-NEXT: ret 74; RV64IF-NEXT: .LBB1_2: # %if.then 75; RV64IF-NEXT: call abort 76 %1 = fcmp oeq float %a, %b 77 br i1 %1, label %if.then, label %if.else 78if.else: 79 ret void 80if.then: 81 tail call void @abort() 82 unreachable 83} 84 85; TODO: generated code quality for this is very poor due to 86; DAGCombiner::visitXOR converting the legal setoeq to setune, which requires 87; expansion. 88define void @br_fcmp_oeq_alt(float %a, float %b) nounwind { 89; RV32IF-LABEL: br_fcmp_oeq_alt: 90; RV32IF: # %bb.0: 91; RV32IF-NEXT: addi sp, sp, -16 92; RV32IF-NEXT: sw ra, 12(sp) 93; RV32IF-NEXT: fmv.w.x ft0, a1 94; RV32IF-NEXT: fmv.w.x ft1, a0 95; RV32IF-NEXT: feq.s a0, ft1, ft0 96; RV32IF-NEXT: xori a0, a0, 1 97; RV32IF-NEXT: beqz a0, .LBB2_2 98; RV32IF-NEXT: # %bb.1: # %if.else 99; RV32IF-NEXT: lw ra, 12(sp) 100; RV32IF-NEXT: addi sp, sp, 16 101; RV32IF-NEXT: ret 102; RV32IF-NEXT: .LBB2_2: # %if.then 103; RV32IF-NEXT: call abort 104; 105; RV64IF-LABEL: br_fcmp_oeq_alt: 106; RV64IF: # %bb.0: 107; RV64IF-NEXT: addi sp, sp, -16 108; RV64IF-NEXT: sd ra, 8(sp) 109; RV64IF-NEXT: fmv.w.x ft0, a1 110; RV64IF-NEXT: fmv.w.x ft1, a0 111; RV64IF-NEXT: feq.s a0, ft1, ft0 112; RV64IF-NEXT: xori a0, a0, 1 113; RV64IF-NEXT: beqz a0, .LBB2_2 114; RV64IF-NEXT: # %bb.1: # %if.else 115; RV64IF-NEXT: ld ra, 8(sp) 116; RV64IF-NEXT: addi sp, sp, 16 117; RV64IF-NEXT: ret 118; RV64IF-NEXT: .LBB2_2: # %if.then 119; RV64IF-NEXT: call abort 120 %1 = fcmp oeq float %a, %b 121 br i1 %1, label %if.then, label %if.else 122if.then: 123 tail call void @abort() 124 unreachable 125if.else: 126 ret void 127} 128 129define void @br_fcmp_ogt(float %a, float %b) nounwind { 130; RV32IF-LABEL: br_fcmp_ogt: 131; RV32IF: # %bb.0: 132; RV32IF-NEXT: addi sp, sp, -16 133; RV32IF-NEXT: sw ra, 12(sp) 134; RV32IF-NEXT: fmv.w.x ft0, a0 135; RV32IF-NEXT: fmv.w.x ft1, a1 136; RV32IF-NEXT: flt.s a0, ft1, ft0 137; RV32IF-NEXT: bnez a0, .LBB3_2 138; RV32IF-NEXT: # %bb.1: # %if.else 139; RV32IF-NEXT: lw ra, 12(sp) 140; RV32IF-NEXT: addi sp, sp, 16 141; RV32IF-NEXT: ret 142; RV32IF-NEXT: .LBB3_2: # %if.then 143; RV32IF-NEXT: call abort 144; 145; RV64IF-LABEL: br_fcmp_ogt: 146; RV64IF: # %bb.0: 147; RV64IF-NEXT: addi sp, sp, -16 148; RV64IF-NEXT: sd ra, 8(sp) 149; RV64IF-NEXT: fmv.w.x ft0, a0 150; RV64IF-NEXT: fmv.w.x ft1, a1 151; RV64IF-NEXT: flt.s a0, ft1, ft0 152; RV64IF-NEXT: bnez a0, .LBB3_2 153; RV64IF-NEXT: # %bb.1: # %if.else 154; RV64IF-NEXT: ld ra, 8(sp) 155; RV64IF-NEXT: addi sp, sp, 16 156; RV64IF-NEXT: ret 157; RV64IF-NEXT: .LBB3_2: # %if.then 158; RV64IF-NEXT: call abort 159 %1 = fcmp ogt float %a, %b 160 br i1 %1, label %if.then, label %if.else 161if.else: 162 ret void 163if.then: 164 tail call void @abort() 165 unreachable 166} 167 168define void @br_fcmp_oge(float %a, float %b) nounwind { 169; RV32IF-LABEL: br_fcmp_oge: 170; RV32IF: # %bb.0: 171; RV32IF-NEXT: addi sp, sp, -16 172; RV32IF-NEXT: sw ra, 12(sp) 173; RV32IF-NEXT: fmv.w.x ft0, a0 174; RV32IF-NEXT: fmv.w.x ft1, a1 175; RV32IF-NEXT: fle.s a0, ft1, ft0 176; RV32IF-NEXT: bnez a0, .LBB4_2 177; RV32IF-NEXT: # %bb.1: # %if.else 178; RV32IF-NEXT: lw ra, 12(sp) 179; RV32IF-NEXT: addi sp, sp, 16 180; RV32IF-NEXT: ret 181; RV32IF-NEXT: .LBB4_2: # %if.then 182; RV32IF-NEXT: call abort 183; 184; RV64IF-LABEL: br_fcmp_oge: 185; RV64IF: # %bb.0: 186; RV64IF-NEXT: addi sp, sp, -16 187; RV64IF-NEXT: sd ra, 8(sp) 188; RV64IF-NEXT: fmv.w.x ft0, a0 189; RV64IF-NEXT: fmv.w.x ft1, a1 190; RV64IF-NEXT: fle.s a0, ft1, ft0 191; RV64IF-NEXT: bnez a0, .LBB4_2 192; RV64IF-NEXT: # %bb.1: # %if.else 193; RV64IF-NEXT: ld ra, 8(sp) 194; RV64IF-NEXT: addi sp, sp, 16 195; RV64IF-NEXT: ret 196; RV64IF-NEXT: .LBB4_2: # %if.then 197; RV64IF-NEXT: call abort 198 %1 = fcmp oge float %a, %b 199 br i1 %1, label %if.then, label %if.else 200if.else: 201 ret void 202if.then: 203 tail call void @abort() 204 unreachable 205} 206 207define void @br_fcmp_olt(float %a, float %b) nounwind { 208; RV32IF-LABEL: br_fcmp_olt: 209; RV32IF: # %bb.0: 210; RV32IF-NEXT: addi sp, sp, -16 211; RV32IF-NEXT: sw ra, 12(sp) 212; RV32IF-NEXT: fmv.w.x ft0, a1 213; RV32IF-NEXT: fmv.w.x ft1, a0 214; RV32IF-NEXT: flt.s a0, ft1, ft0 215; RV32IF-NEXT: bnez a0, .LBB5_2 216; RV32IF-NEXT: # %bb.1: # %if.else 217; RV32IF-NEXT: lw ra, 12(sp) 218; RV32IF-NEXT: addi sp, sp, 16 219; RV32IF-NEXT: ret 220; RV32IF-NEXT: .LBB5_2: # %if.then 221; RV32IF-NEXT: call abort 222; 223; RV64IF-LABEL: br_fcmp_olt: 224; RV64IF: # %bb.0: 225; RV64IF-NEXT: addi sp, sp, -16 226; RV64IF-NEXT: sd ra, 8(sp) 227; RV64IF-NEXT: fmv.w.x ft0, a1 228; RV64IF-NEXT: fmv.w.x ft1, a0 229; RV64IF-NEXT: flt.s a0, ft1, ft0 230; RV64IF-NEXT: bnez a0, .LBB5_2 231; RV64IF-NEXT: # %bb.1: # %if.else 232; RV64IF-NEXT: ld ra, 8(sp) 233; RV64IF-NEXT: addi sp, sp, 16 234; RV64IF-NEXT: ret 235; RV64IF-NEXT: .LBB5_2: # %if.then 236; RV64IF-NEXT: call abort 237 %1 = fcmp olt float %a, %b 238 br i1 %1, label %if.then, label %if.else 239if.else: 240 ret void 241if.then: 242 tail call void @abort() 243 unreachable 244} 245 246define void @br_fcmp_ole(float %a, float %b) nounwind { 247; RV32IF-LABEL: br_fcmp_ole: 248; RV32IF: # %bb.0: 249; RV32IF-NEXT: addi sp, sp, -16 250; RV32IF-NEXT: sw ra, 12(sp) 251; RV32IF-NEXT: fmv.w.x ft0, a1 252; RV32IF-NEXT: fmv.w.x ft1, a0 253; RV32IF-NEXT: fle.s a0, ft1, ft0 254; RV32IF-NEXT: bnez a0, .LBB6_2 255; RV32IF-NEXT: # %bb.1: # %if.else 256; RV32IF-NEXT: lw ra, 12(sp) 257; RV32IF-NEXT: addi sp, sp, 16 258; RV32IF-NEXT: ret 259; RV32IF-NEXT: .LBB6_2: # %if.then 260; RV32IF-NEXT: call abort 261; 262; RV64IF-LABEL: br_fcmp_ole: 263; RV64IF: # %bb.0: 264; RV64IF-NEXT: addi sp, sp, -16 265; RV64IF-NEXT: sd ra, 8(sp) 266; RV64IF-NEXT: fmv.w.x ft0, a1 267; RV64IF-NEXT: fmv.w.x ft1, a0 268; RV64IF-NEXT: fle.s a0, ft1, ft0 269; RV64IF-NEXT: bnez a0, .LBB6_2 270; RV64IF-NEXT: # %bb.1: # %if.else 271; RV64IF-NEXT: ld ra, 8(sp) 272; RV64IF-NEXT: addi sp, sp, 16 273; RV64IF-NEXT: ret 274; RV64IF-NEXT: .LBB6_2: # %if.then 275; RV64IF-NEXT: call abort 276 %1 = fcmp ole float %a, %b 277 br i1 %1, label %if.then, label %if.else 278if.else: 279 ret void 280if.then: 281 tail call void @abort() 282 unreachable 283} 284 285; TODO: feq.s+sltiu+bne -> feq.s+beq 286define void @br_fcmp_one(float %a, float %b) nounwind { 287; RV32IF-LABEL: br_fcmp_one: 288; RV32IF: # %bb.0: 289; RV32IF-NEXT: addi sp, sp, -16 290; RV32IF-NEXT: sw ra, 12(sp) 291; RV32IF-NEXT: fmv.w.x ft0, a0 292; RV32IF-NEXT: fmv.w.x ft1, a1 293; RV32IF-NEXT: feq.s a0, ft1, ft1 294; RV32IF-NEXT: feq.s a1, ft0, ft0 295; RV32IF-NEXT: and a0, a1, a0 296; RV32IF-NEXT: feq.s a1, ft0, ft1 297; RV32IF-NEXT: not a1, a1 298; RV32IF-NEXT: and a0, a1, a0 299; RV32IF-NEXT: bnez a0, .LBB7_2 300; RV32IF-NEXT: # %bb.1: # %if.else 301; RV32IF-NEXT: lw ra, 12(sp) 302; RV32IF-NEXT: addi sp, sp, 16 303; RV32IF-NEXT: ret 304; RV32IF-NEXT: .LBB7_2: # %if.then 305; RV32IF-NEXT: call abort 306; 307; RV64IF-LABEL: br_fcmp_one: 308; RV64IF: # %bb.0: 309; RV64IF-NEXT: addi sp, sp, -16 310; RV64IF-NEXT: sd ra, 8(sp) 311; RV64IF-NEXT: fmv.w.x ft0, a0 312; RV64IF-NEXT: fmv.w.x ft1, a1 313; RV64IF-NEXT: feq.s a0, ft1, ft1 314; RV64IF-NEXT: feq.s a1, ft0, ft0 315; RV64IF-NEXT: and a0, a1, a0 316; RV64IF-NEXT: feq.s a1, ft0, ft1 317; RV64IF-NEXT: not a1, a1 318; RV64IF-NEXT: and a0, a1, a0 319; RV64IF-NEXT: bnez a0, .LBB7_2 320; RV64IF-NEXT: # %bb.1: # %if.else 321; RV64IF-NEXT: ld ra, 8(sp) 322; RV64IF-NEXT: addi sp, sp, 16 323; RV64IF-NEXT: ret 324; RV64IF-NEXT: .LBB7_2: # %if.then 325; RV64IF-NEXT: call abort 326 %1 = fcmp one float %a, %b 327 br i1 %1, label %if.then, label %if.else 328if.else: 329 ret void 330if.then: 331 tail call void @abort() 332 unreachable 333} 334 335define void @br_fcmp_ord(float %a, float %b) nounwind { 336; RV32IF-LABEL: br_fcmp_ord: 337; RV32IF: # %bb.0: 338; RV32IF-NEXT: addi sp, sp, -16 339; RV32IF-NEXT: sw ra, 12(sp) 340; RV32IF-NEXT: fmv.w.x ft0, a0 341; RV32IF-NEXT: fmv.w.x ft1, a1 342; RV32IF-NEXT: feq.s a0, ft1, ft1 343; RV32IF-NEXT: feq.s a1, ft0, ft0 344; RV32IF-NEXT: and a0, a1, a0 345; RV32IF-NEXT: bnez a0, .LBB8_2 346; RV32IF-NEXT: # %bb.1: # %if.else 347; RV32IF-NEXT: lw ra, 12(sp) 348; RV32IF-NEXT: addi sp, sp, 16 349; RV32IF-NEXT: ret 350; RV32IF-NEXT: .LBB8_2: # %if.then 351; RV32IF-NEXT: call abort 352; 353; RV64IF-LABEL: br_fcmp_ord: 354; RV64IF: # %bb.0: 355; RV64IF-NEXT: addi sp, sp, -16 356; RV64IF-NEXT: sd ra, 8(sp) 357; RV64IF-NEXT: fmv.w.x ft0, a0 358; RV64IF-NEXT: fmv.w.x ft1, a1 359; RV64IF-NEXT: feq.s a0, ft1, ft1 360; RV64IF-NEXT: feq.s a1, ft0, ft0 361; RV64IF-NEXT: and a0, a1, a0 362; RV64IF-NEXT: bnez a0, .LBB8_2 363; RV64IF-NEXT: # %bb.1: # %if.else 364; RV64IF-NEXT: ld ra, 8(sp) 365; RV64IF-NEXT: addi sp, sp, 16 366; RV64IF-NEXT: ret 367; RV64IF-NEXT: .LBB8_2: # %if.then 368; RV64IF-NEXT: call abort 369 %1 = fcmp ord float %a, %b 370 br i1 %1, label %if.then, label %if.else 371if.else: 372 ret void 373if.then: 374 tail call void @abort() 375 unreachable 376} 377 378define void @br_fcmp_ueq(float %a, float %b) nounwind { 379; RV32IF-LABEL: br_fcmp_ueq: 380; RV32IF: # %bb.0: 381; RV32IF-NEXT: addi sp, sp, -16 382; RV32IF-NEXT: sw ra, 12(sp) 383; RV32IF-NEXT: fmv.w.x ft0, a1 384; RV32IF-NEXT: fmv.w.x ft1, a0 385; RV32IF-NEXT: feq.s a0, ft1, ft0 386; RV32IF-NEXT: feq.s a1, ft0, ft0 387; RV32IF-NEXT: feq.s a2, ft1, ft1 388; RV32IF-NEXT: and a1, a2, a1 389; RV32IF-NEXT: seqz a1, a1 390; RV32IF-NEXT: or a0, a0, a1 391; RV32IF-NEXT: bnez a0, .LBB9_2 392; RV32IF-NEXT: # %bb.1: # %if.else 393; RV32IF-NEXT: lw ra, 12(sp) 394; RV32IF-NEXT: addi sp, sp, 16 395; RV32IF-NEXT: ret 396; RV32IF-NEXT: .LBB9_2: # %if.then 397; RV32IF-NEXT: call abort 398; 399; RV64IF-LABEL: br_fcmp_ueq: 400; RV64IF: # %bb.0: 401; RV64IF-NEXT: addi sp, sp, -16 402; RV64IF-NEXT: sd ra, 8(sp) 403; RV64IF-NEXT: fmv.w.x ft0, a1 404; RV64IF-NEXT: fmv.w.x ft1, a0 405; RV64IF-NEXT: feq.s a0, ft1, ft0 406; RV64IF-NEXT: feq.s a1, ft0, ft0 407; RV64IF-NEXT: feq.s a2, ft1, ft1 408; RV64IF-NEXT: and a1, a2, a1 409; RV64IF-NEXT: seqz a1, a1 410; RV64IF-NEXT: or a0, a0, a1 411; RV64IF-NEXT: bnez a0, .LBB9_2 412; RV64IF-NEXT: # %bb.1: # %if.else 413; RV64IF-NEXT: ld ra, 8(sp) 414; RV64IF-NEXT: addi sp, sp, 16 415; RV64IF-NEXT: ret 416; RV64IF-NEXT: .LBB9_2: # %if.then 417; RV64IF-NEXT: call abort 418 %1 = fcmp ueq float %a, %b 419 br i1 %1, label %if.then, label %if.else 420if.else: 421 ret void 422if.then: 423 tail call void @abort() 424 unreachable 425} 426 427define void @br_fcmp_ugt(float %a, float %b) nounwind { 428; RV32IF-LABEL: br_fcmp_ugt: 429; RV32IF: # %bb.0: 430; RV32IF-NEXT: addi sp, sp, -16 431; RV32IF-NEXT: sw ra, 12(sp) 432; RV32IF-NEXT: fmv.w.x ft0, a1 433; RV32IF-NEXT: fmv.w.x ft1, a0 434; RV32IF-NEXT: fle.s a0, ft1, ft0 435; RV32IF-NEXT: xori a0, a0, 1 436; RV32IF-NEXT: bnez a0, .LBB10_2 437; RV32IF-NEXT: # %bb.1: # %if.else 438; RV32IF-NEXT: lw ra, 12(sp) 439; RV32IF-NEXT: addi sp, sp, 16 440; RV32IF-NEXT: ret 441; RV32IF-NEXT: .LBB10_2: # %if.then 442; RV32IF-NEXT: call abort 443; 444; RV64IF-LABEL: br_fcmp_ugt: 445; RV64IF: # %bb.0: 446; RV64IF-NEXT: addi sp, sp, -16 447; RV64IF-NEXT: sd ra, 8(sp) 448; RV64IF-NEXT: fmv.w.x ft0, a1 449; RV64IF-NEXT: fmv.w.x ft1, a0 450; RV64IF-NEXT: fle.s a0, ft1, ft0 451; RV64IF-NEXT: xori a0, a0, 1 452; RV64IF-NEXT: bnez a0, .LBB10_2 453; RV64IF-NEXT: # %bb.1: # %if.else 454; RV64IF-NEXT: ld ra, 8(sp) 455; RV64IF-NEXT: addi sp, sp, 16 456; RV64IF-NEXT: ret 457; RV64IF-NEXT: .LBB10_2: # %if.then 458; RV64IF-NEXT: call abort 459 %1 = fcmp ugt float %a, %b 460 br i1 %1, label %if.then, label %if.else 461if.else: 462 ret void 463if.then: 464 tail call void @abort() 465 unreachable 466} 467 468define void @br_fcmp_uge(float %a, float %b) nounwind { 469; RV32IF-LABEL: br_fcmp_uge: 470; RV32IF: # %bb.0: 471; RV32IF-NEXT: addi sp, sp, -16 472; RV32IF-NEXT: sw ra, 12(sp) 473; RV32IF-NEXT: fmv.w.x ft0, a1 474; RV32IF-NEXT: fmv.w.x ft1, a0 475; RV32IF-NEXT: flt.s a0, ft1, ft0 476; RV32IF-NEXT: xori a0, a0, 1 477; RV32IF-NEXT: bnez a0, .LBB11_2 478; RV32IF-NEXT: # %bb.1: # %if.else 479; RV32IF-NEXT: lw ra, 12(sp) 480; RV32IF-NEXT: addi sp, sp, 16 481; RV32IF-NEXT: ret 482; RV32IF-NEXT: .LBB11_2: # %if.then 483; RV32IF-NEXT: call abort 484; 485; RV64IF-LABEL: br_fcmp_uge: 486; RV64IF: # %bb.0: 487; RV64IF-NEXT: addi sp, sp, -16 488; RV64IF-NEXT: sd ra, 8(sp) 489; RV64IF-NEXT: fmv.w.x ft0, a1 490; RV64IF-NEXT: fmv.w.x ft1, a0 491; RV64IF-NEXT: flt.s a0, ft1, ft0 492; RV64IF-NEXT: xori a0, a0, 1 493; RV64IF-NEXT: bnez a0, .LBB11_2 494; RV64IF-NEXT: # %bb.1: # %if.else 495; RV64IF-NEXT: ld ra, 8(sp) 496; RV64IF-NEXT: addi sp, sp, 16 497; RV64IF-NEXT: ret 498; RV64IF-NEXT: .LBB11_2: # %if.then 499; RV64IF-NEXT: call abort 500 %1 = fcmp uge float %a, %b 501 br i1 %1, label %if.then, label %if.else 502if.else: 503 ret void 504if.then: 505 tail call void @abort() 506 unreachable 507} 508 509define void @br_fcmp_ult(float %a, float %b) nounwind { 510; RV32IF-LABEL: br_fcmp_ult: 511; RV32IF: # %bb.0: 512; RV32IF-NEXT: addi sp, sp, -16 513; RV32IF-NEXT: sw ra, 12(sp) 514; RV32IF-NEXT: fmv.w.x ft0, a0 515; RV32IF-NEXT: fmv.w.x ft1, a1 516; RV32IF-NEXT: fle.s a0, ft1, ft0 517; RV32IF-NEXT: xori a0, a0, 1 518; RV32IF-NEXT: bnez a0, .LBB12_2 519; RV32IF-NEXT: # %bb.1: # %if.else 520; RV32IF-NEXT: lw ra, 12(sp) 521; RV32IF-NEXT: addi sp, sp, 16 522; RV32IF-NEXT: ret 523; RV32IF-NEXT: .LBB12_2: # %if.then 524; RV32IF-NEXT: call abort 525; 526; RV64IF-LABEL: br_fcmp_ult: 527; RV64IF: # %bb.0: 528; RV64IF-NEXT: addi sp, sp, -16 529; RV64IF-NEXT: sd ra, 8(sp) 530; RV64IF-NEXT: fmv.w.x ft0, a0 531; RV64IF-NEXT: fmv.w.x ft1, a1 532; RV64IF-NEXT: fle.s a0, ft1, ft0 533; RV64IF-NEXT: xori a0, a0, 1 534; RV64IF-NEXT: bnez a0, .LBB12_2 535; RV64IF-NEXT: # %bb.1: # %if.else 536; RV64IF-NEXT: ld ra, 8(sp) 537; RV64IF-NEXT: addi sp, sp, 16 538; RV64IF-NEXT: ret 539; RV64IF-NEXT: .LBB12_2: # %if.then 540; RV64IF-NEXT: call abort 541 %1 = fcmp ult float %a, %b 542 br i1 %1, label %if.then, label %if.else 543if.else: 544 ret void 545if.then: 546 tail call void @abort() 547 unreachable 548} 549 550define void @br_fcmp_ule(float %a, float %b) nounwind { 551; RV32IF-LABEL: br_fcmp_ule: 552; RV32IF: # %bb.0: 553; RV32IF-NEXT: addi sp, sp, -16 554; RV32IF-NEXT: sw ra, 12(sp) 555; RV32IF-NEXT: fmv.w.x ft0, a0 556; RV32IF-NEXT: fmv.w.x ft1, a1 557; RV32IF-NEXT: flt.s a0, ft1, ft0 558; RV32IF-NEXT: xori a0, a0, 1 559; RV32IF-NEXT: bnez a0, .LBB13_2 560; RV32IF-NEXT: # %bb.1: # %if.else 561; RV32IF-NEXT: lw ra, 12(sp) 562; RV32IF-NEXT: addi sp, sp, 16 563; RV32IF-NEXT: ret 564; RV32IF-NEXT: .LBB13_2: # %if.then 565; RV32IF-NEXT: call abort 566; 567; RV64IF-LABEL: br_fcmp_ule: 568; RV64IF: # %bb.0: 569; RV64IF-NEXT: addi sp, sp, -16 570; RV64IF-NEXT: sd ra, 8(sp) 571; RV64IF-NEXT: fmv.w.x ft0, a0 572; RV64IF-NEXT: fmv.w.x ft1, a1 573; RV64IF-NEXT: flt.s a0, ft1, ft0 574; RV64IF-NEXT: xori a0, a0, 1 575; RV64IF-NEXT: bnez a0, .LBB13_2 576; RV64IF-NEXT: # %bb.1: # %if.else 577; RV64IF-NEXT: ld ra, 8(sp) 578; RV64IF-NEXT: addi sp, sp, 16 579; RV64IF-NEXT: ret 580; RV64IF-NEXT: .LBB13_2: # %if.then 581; RV64IF-NEXT: call abort 582 %1 = fcmp ule float %a, %b 583 br i1 %1, label %if.then, label %if.else 584if.else: 585 ret void 586if.then: 587 tail call void @abort() 588 unreachable 589} 590 591define void @br_fcmp_une(float %a, float %b) nounwind { 592; RV32IF-LABEL: br_fcmp_une: 593; RV32IF: # %bb.0: 594; RV32IF-NEXT: addi sp, sp, -16 595; RV32IF-NEXT: sw ra, 12(sp) 596; RV32IF-NEXT: fmv.w.x ft0, a1 597; RV32IF-NEXT: fmv.w.x ft1, a0 598; RV32IF-NEXT: feq.s a0, ft1, ft0 599; RV32IF-NEXT: xori a0, a0, 1 600; RV32IF-NEXT: bnez a0, .LBB14_2 601; RV32IF-NEXT: # %bb.1: # %if.else 602; RV32IF-NEXT: lw ra, 12(sp) 603; RV32IF-NEXT: addi sp, sp, 16 604; RV32IF-NEXT: ret 605; RV32IF-NEXT: .LBB14_2: # %if.then 606; RV32IF-NEXT: call abort 607; 608; RV64IF-LABEL: br_fcmp_une: 609; RV64IF: # %bb.0: 610; RV64IF-NEXT: addi sp, sp, -16 611; RV64IF-NEXT: sd ra, 8(sp) 612; RV64IF-NEXT: fmv.w.x ft0, a1 613; RV64IF-NEXT: fmv.w.x ft1, a0 614; RV64IF-NEXT: feq.s a0, ft1, ft0 615; RV64IF-NEXT: xori a0, a0, 1 616; RV64IF-NEXT: bnez a0, .LBB14_2 617; RV64IF-NEXT: # %bb.1: # %if.else 618; RV64IF-NEXT: ld ra, 8(sp) 619; RV64IF-NEXT: addi sp, sp, 16 620; RV64IF-NEXT: ret 621; RV64IF-NEXT: .LBB14_2: # %if.then 622; RV64IF-NEXT: call abort 623 %1 = fcmp une float %a, %b 624 br i1 %1, label %if.then, label %if.else 625if.else: 626 ret void 627if.then: 628 tail call void @abort() 629 unreachable 630} 631 632define void @br_fcmp_uno(float %a, float %b) nounwind { 633; TODO: sltiu+bne -> beq 634; RV32IF-LABEL: br_fcmp_uno: 635; RV32IF: # %bb.0: 636; RV32IF-NEXT: addi sp, sp, -16 637; RV32IF-NEXT: sw ra, 12(sp) 638; RV32IF-NEXT: fmv.w.x ft0, a0 639; RV32IF-NEXT: fmv.w.x ft1, a1 640; RV32IF-NEXT: feq.s a0, ft1, ft1 641; RV32IF-NEXT: feq.s a1, ft0, ft0 642; RV32IF-NEXT: and a0, a1, a0 643; RV32IF-NEXT: seqz a0, a0 644; RV32IF-NEXT: bnez a0, .LBB15_2 645; RV32IF-NEXT: # %bb.1: # %if.else 646; RV32IF-NEXT: lw ra, 12(sp) 647; RV32IF-NEXT: addi sp, sp, 16 648; RV32IF-NEXT: ret 649; RV32IF-NEXT: .LBB15_2: # %if.then 650; RV32IF-NEXT: call abort 651; 652; RV64IF-LABEL: br_fcmp_uno: 653; RV64IF: # %bb.0: 654; RV64IF-NEXT: addi sp, sp, -16 655; RV64IF-NEXT: sd ra, 8(sp) 656; RV64IF-NEXT: fmv.w.x ft0, a0 657; RV64IF-NEXT: fmv.w.x ft1, a1 658; RV64IF-NEXT: feq.s a0, ft1, ft1 659; RV64IF-NEXT: feq.s a1, ft0, ft0 660; RV64IF-NEXT: and a0, a1, a0 661; RV64IF-NEXT: seqz a0, a0 662; RV64IF-NEXT: bnez a0, .LBB15_2 663; RV64IF-NEXT: # %bb.1: # %if.else 664; RV64IF-NEXT: ld ra, 8(sp) 665; RV64IF-NEXT: addi sp, sp, 16 666; RV64IF-NEXT: ret 667; RV64IF-NEXT: .LBB15_2: # %if.then 668; RV64IF-NEXT: call abort 669 %1 = fcmp uno float %a, %b 670 br i1 %1, label %if.then, label %if.else 671if.else: 672 ret void 673if.then: 674 tail call void @abort() 675 unreachable 676} 677 678define void @br_fcmp_true(float %a, float %b) nounwind { 679; RV32IF-LABEL: br_fcmp_true: 680; RV32IF: # %bb.0: 681; RV32IF-NEXT: addi sp, sp, -16 682; RV32IF-NEXT: sw ra, 12(sp) 683; RV32IF-NEXT: addi a0, zero, 1 684; RV32IF-NEXT: bnez a0, .LBB16_2 685; RV32IF-NEXT: # %bb.1: # %if.else 686; RV32IF-NEXT: lw ra, 12(sp) 687; RV32IF-NEXT: addi sp, sp, 16 688; RV32IF-NEXT: ret 689; RV32IF-NEXT: .LBB16_2: # %if.then 690; RV32IF-NEXT: call abort 691; 692; RV64IF-LABEL: br_fcmp_true: 693; RV64IF: # %bb.0: 694; RV64IF-NEXT: addi sp, sp, -16 695; RV64IF-NEXT: sd ra, 8(sp) 696; RV64IF-NEXT: addi a0, zero, 1 697; RV64IF-NEXT: bnez a0, .LBB16_2 698; RV64IF-NEXT: # %bb.1: # %if.else 699; RV64IF-NEXT: ld ra, 8(sp) 700; RV64IF-NEXT: addi sp, sp, 16 701; RV64IF-NEXT: ret 702; RV64IF-NEXT: .LBB16_2: # %if.then 703; RV64IF-NEXT: call abort 704 %1 = fcmp true float %a, %b 705 br i1 %1, label %if.then, label %if.else 706if.else: 707 ret void 708if.then: 709 tail call void @abort() 710 unreachable 711} 712 713; This test exists primarily to trigger RISCVInstrInfo::storeRegToStackSlot 714; and RISCVInstrInfo::loadRegFromStackSlot 715define i32 @br_fcmp_store_load_stack_slot(float %a, float %b) nounwind { 716; TODO: addi %lo(.LCPI17_0) should be merged in to the following flw 717; RV32IF-LABEL: br_fcmp_store_load_stack_slot: 718; RV32IF: # %bb.0: # %entry 719; RV32IF-NEXT: addi sp, sp, -16 720; RV32IF-NEXT: sw ra, 12(sp) 721; RV32IF-NEXT: mv a0, zero 722; RV32IF-NEXT: call dummy 723; RV32IF-NEXT: fmv.w.x ft0, a0 724; RV32IF-NEXT: fmv.w.x ft1, zero 725; RV32IF-NEXT: fsw ft1, 8(sp) 726; RV32IF-NEXT: feq.s a0, ft0, ft1 727; RV32IF-NEXT: beqz a0, .LBB17_3 728; RV32IF-NEXT: # %bb.1: # %if.end 729; RV32IF-NEXT: mv a0, zero 730; RV32IF-NEXT: call dummy 731; RV32IF-NEXT: fmv.w.x ft0, a0 732; RV32IF-NEXT: flw ft1, 8(sp) 733; RV32IF-NEXT: feq.s a0, ft0, ft1 734; RV32IF-NEXT: beqz a0, .LBB17_3 735; RV32IF-NEXT: # %bb.2: # %if.end4 736; RV32IF-NEXT: mv a0, zero 737; RV32IF-NEXT: lw ra, 12(sp) 738; RV32IF-NEXT: addi sp, sp, 16 739; RV32IF-NEXT: ret 740; RV32IF-NEXT: .LBB17_3: # %if.then 741; RV32IF-NEXT: call abort 742; 743; RV64IF-LABEL: br_fcmp_store_load_stack_slot: 744; RV64IF: # %bb.0: # %entry 745; RV64IF-NEXT: addi sp, sp, -32 746; RV64IF-NEXT: sd ra, 24(sp) 747; RV64IF-NEXT: sd s0, 16(sp) 748; RV64IF-NEXT: fmv.w.x ft0, zero 749; RV64IF-NEXT: fsw ft0, 12(sp) 750; RV64IF-NEXT: fmv.x.w s0, ft0 751; RV64IF-NEXT: mv a0, s0 752; RV64IF-NEXT: call dummy 753; RV64IF-NEXT: fmv.w.x ft0, a0 754; RV64IF-NEXT: flw ft1, 12(sp) 755; RV64IF-NEXT: feq.s a0, ft0, ft1 756; RV64IF-NEXT: beqz a0, .LBB17_3 757; RV64IF-NEXT: # %bb.1: # %if.end 758; RV64IF-NEXT: mv a0, s0 759; RV64IF-NEXT: call dummy 760; RV64IF-NEXT: fmv.w.x ft0, a0 761; RV64IF-NEXT: flw ft1, 12(sp) 762; RV64IF-NEXT: feq.s a0, ft0, ft1 763; RV64IF-NEXT: beqz a0, .LBB17_3 764; RV64IF-NEXT: # %bb.2: # %if.end4 765; RV64IF-NEXT: mv a0, zero 766; RV64IF-NEXT: ld s0, 16(sp) 767; RV64IF-NEXT: ld ra, 24(sp) 768; RV64IF-NEXT: addi sp, sp, 32 769; RV64IF-NEXT: ret 770; RV64IF-NEXT: .LBB17_3: # %if.then 771; RV64IF-NEXT: call abort 772entry: 773 %call = call float @dummy(float 0.000000e+00) 774 %cmp = fcmp une float %call, 0.000000e+00 775 br i1 %cmp, label %if.then, label %if.end 776 777if.then: 778 call void @abort() 779 unreachable 780 781if.end: 782 %call1 = call float @dummy(float 0.000000e+00) 783 %cmp2 = fcmp une float %call1, 0.000000e+00 784 br i1 %cmp2, label %if.then3, label %if.end4 785 786if.then3: 787 call void @abort() 788 unreachable 789 790if.end4: 791 ret i32 0 792} 793