1; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py 2; RUN: llc -mtriple=riscv32 -disable-block-placement -verify-machineinstrs < %s \ 3; RUN: | FileCheck -check-prefixes=RV32I %s 4; RUN: llc -mtriple=riscv64 -disable-block-placement -verify-machineinstrs < %s \ 5; RUN: | FileCheck -check-prefixes=RV64I %s 6; RUN: llc -mtriple=riscv64 -mattr=+xmipscmove -verify-machineinstrs < %s \ 7; RUN: | FileCheck -check-prefix=RV64I-CCMOV %s 8 9define signext i32 @foo(i32 signext %a, ptr %b) nounwind { 10; RV32I-LABEL: foo: 11; RV32I: # %bb.0: 12; RV32I-NEXT: lw a2, 0(a1) 13; RV32I-NEXT: beq a0, a2, .LBB0_2 14; RV32I-NEXT: # %bb.1: 15; RV32I-NEXT: mv a0, a2 16; RV32I-NEXT: .LBB0_2: 17; RV32I-NEXT: lw a2, 0(a1) 18; RV32I-NEXT: bne a0, a2, .LBB0_4 19; RV32I-NEXT: # %bb.3: 20; RV32I-NEXT: mv a0, a2 21; RV32I-NEXT: .LBB0_4: 22; RV32I-NEXT: lw a2, 0(a1) 23; RV32I-NEXT: bltu a2, a0, .LBB0_6 24; RV32I-NEXT: # %bb.5: 25; RV32I-NEXT: mv a0, a2 26; RV32I-NEXT: .LBB0_6: 27; RV32I-NEXT: lw a2, 0(a1) 28; RV32I-NEXT: bgeu a0, a2, .LBB0_8 29; RV32I-NEXT: # %bb.7: 30; RV32I-NEXT: mv a0, a2 31; RV32I-NEXT: .LBB0_8: 32; RV32I-NEXT: lw a2, 0(a1) 33; RV32I-NEXT: bltu a0, a2, .LBB0_10 34; RV32I-NEXT: # %bb.9: 35; RV32I-NEXT: mv a0, a2 36; RV32I-NEXT: .LBB0_10: 37; RV32I-NEXT: lw a2, 0(a1) 38; RV32I-NEXT: bgeu a2, a0, .LBB0_12 39; RV32I-NEXT: # %bb.11: 40; RV32I-NEXT: mv a0, a2 41; RV32I-NEXT: .LBB0_12: 42; RV32I-NEXT: lw a2, 0(a1) 43; RV32I-NEXT: blt a2, a0, .LBB0_14 44; RV32I-NEXT: # %bb.13: 45; RV32I-NEXT: mv a0, a2 46; RV32I-NEXT: .LBB0_14: 47; RV32I-NEXT: lw a2, 0(a1) 48; RV32I-NEXT: bge a0, a2, .LBB0_16 49; RV32I-NEXT: # %bb.15: 50; RV32I-NEXT: mv a0, a2 51; RV32I-NEXT: .LBB0_16: 52; RV32I-NEXT: lw a2, 0(a1) 53; RV32I-NEXT: blt a0, a2, .LBB0_18 54; RV32I-NEXT: # %bb.17: 55; RV32I-NEXT: mv a0, a2 56; RV32I-NEXT: .LBB0_18: 57; RV32I-NEXT: lw a2, 0(a1) 58; RV32I-NEXT: bge a2, a0, .LBB0_20 59; RV32I-NEXT: # %bb.19: 60; RV32I-NEXT: mv a0, a2 61; RV32I-NEXT: .LBB0_20: 62; RV32I-NEXT: lw a2, 0(a1) 63; RV32I-NEXT: blez a2, .LBB0_22 64; RV32I-NEXT: # %bb.21: 65; RV32I-NEXT: mv a0, a2 66; RV32I-NEXT: .LBB0_22: 67; RV32I-NEXT: lw a3, 0(a1) 68; RV32I-NEXT: bgez a2, .LBB0_24 69; RV32I-NEXT: # %bb.23: 70; RV32I-NEXT: mv a0, a3 71; RV32I-NEXT: .LBB0_24: 72; RV32I-NEXT: lw a3, 0(a1) 73; RV32I-NEXT: li a4, 1024 74; RV32I-NEXT: blt a4, a3, .LBB0_26 75; RV32I-NEXT: # %bb.25: 76; RV32I-NEXT: mv a0, a3 77; RV32I-NEXT: .LBB0_26: 78; RV32I-NEXT: lw a1, 0(a1) 79; RV32I-NEXT: li a3, 2046 80; RV32I-NEXT: bltu a3, a2, .LBB0_28 81; RV32I-NEXT: # %bb.27: 82; RV32I-NEXT: mv a0, a1 83; RV32I-NEXT: .LBB0_28: 84; RV32I-NEXT: ret 85; 86; RV64I-LABEL: foo: 87; RV64I: # %bb.0: 88; RV64I-NEXT: lw a2, 0(a1) 89; RV64I-NEXT: beq a0, a2, .LBB0_2 90; RV64I-NEXT: # %bb.1: 91; RV64I-NEXT: mv a0, a2 92; RV64I-NEXT: .LBB0_2: 93; RV64I-NEXT: lw a2, 0(a1) 94; RV64I-NEXT: bne a0, a2, .LBB0_4 95; RV64I-NEXT: # %bb.3: 96; RV64I-NEXT: mv a0, a2 97; RV64I-NEXT: .LBB0_4: 98; RV64I-NEXT: lw a2, 0(a1) 99; RV64I-NEXT: bltu a2, a0, .LBB0_6 100; RV64I-NEXT: # %bb.5: 101; RV64I-NEXT: mv a0, a2 102; RV64I-NEXT: .LBB0_6: 103; RV64I-NEXT: lw a2, 0(a1) 104; RV64I-NEXT: bgeu a0, a2, .LBB0_8 105; RV64I-NEXT: # %bb.7: 106; RV64I-NEXT: mv a0, a2 107; RV64I-NEXT: .LBB0_8: 108; RV64I-NEXT: lw a2, 0(a1) 109; RV64I-NEXT: bltu a0, a2, .LBB0_10 110; RV64I-NEXT: # %bb.9: 111; RV64I-NEXT: mv a0, a2 112; RV64I-NEXT: .LBB0_10: 113; RV64I-NEXT: lw a2, 0(a1) 114; RV64I-NEXT: bgeu a2, a0, .LBB0_12 115; RV64I-NEXT: # %bb.11: 116; RV64I-NEXT: mv a0, a2 117; RV64I-NEXT: .LBB0_12: 118; RV64I-NEXT: lw a2, 0(a1) 119; RV64I-NEXT: blt a2, a0, .LBB0_14 120; RV64I-NEXT: # %bb.13: 121; RV64I-NEXT: mv a0, a2 122; RV64I-NEXT: .LBB0_14: 123; RV64I-NEXT: lw a2, 0(a1) 124; RV64I-NEXT: bge a0, a2, .LBB0_16 125; RV64I-NEXT: # %bb.15: 126; RV64I-NEXT: mv a0, a2 127; RV64I-NEXT: .LBB0_16: 128; RV64I-NEXT: lw a2, 0(a1) 129; RV64I-NEXT: blt a0, a2, .LBB0_18 130; RV64I-NEXT: # %bb.17: 131; RV64I-NEXT: mv a0, a2 132; RV64I-NEXT: .LBB0_18: 133; RV64I-NEXT: lw a2, 0(a1) 134; RV64I-NEXT: bge a2, a0, .LBB0_20 135; RV64I-NEXT: # %bb.19: 136; RV64I-NEXT: mv a0, a2 137; RV64I-NEXT: .LBB0_20: 138; RV64I-NEXT: lw a2, 0(a1) 139; RV64I-NEXT: blez a2, .LBB0_22 140; RV64I-NEXT: # %bb.21: 141; RV64I-NEXT: mv a0, a2 142; RV64I-NEXT: .LBB0_22: 143; RV64I-NEXT: lw a3, 0(a1) 144; RV64I-NEXT: bgez a2, .LBB0_24 145; RV64I-NEXT: # %bb.23: 146; RV64I-NEXT: mv a0, a3 147; RV64I-NEXT: .LBB0_24: 148; RV64I-NEXT: lw a3, 0(a1) 149; RV64I-NEXT: li a4, 1024 150; RV64I-NEXT: blt a4, a3, .LBB0_26 151; RV64I-NEXT: # %bb.25: 152; RV64I-NEXT: mv a0, a3 153; RV64I-NEXT: .LBB0_26: 154; RV64I-NEXT: lw a1, 0(a1) 155; RV64I-NEXT: li a3, 2046 156; RV64I-NEXT: bltu a3, a2, .LBB0_28 157; RV64I-NEXT: # %bb.27: 158; RV64I-NEXT: mv a0, a1 159; RV64I-NEXT: .LBB0_28: 160; RV64I-NEXT: ret 161; 162; RV64I-CCMOV-LABEL: foo: 163; RV64I-CCMOV: # %bb.0: 164; RV64I-CCMOV-NEXT: lw a2, 0(a1) 165; RV64I-CCMOV-NEXT: lw a3, 0(a1) 166; RV64I-CCMOV-NEXT: lw a4, 0(a1) 167; RV64I-CCMOV-NEXT: lw a5, 0(a1) 168; RV64I-CCMOV-NEXT: xor a6, a0, a2 169; RV64I-CCMOV-NEXT: mips.ccmov a0, a6, a2, a0 170; RV64I-CCMOV-NEXT: xor a2, a0, a3 171; RV64I-CCMOV-NEXT: mips.ccmov a0, a2, a0, a3 172; RV64I-CCMOV-NEXT: lw a2, 0(a1) 173; RV64I-CCMOV-NEXT: sltu a3, a4, a0 174; RV64I-CCMOV-NEXT: mips.ccmov a0, a3, a0, a4 175; RV64I-CCMOV-NEXT: lw a3, 0(a1) 176; RV64I-CCMOV-NEXT: sltu a4, a0, a5 177; RV64I-CCMOV-NEXT: mips.ccmov a0, a4, a5, a0 178; RV64I-CCMOV-NEXT: lw a4, 0(a1) 179; RV64I-CCMOV-NEXT: sltu a5, a0, a2 180; RV64I-CCMOV-NEXT: mips.ccmov a0, a5, a0, a2 181; RV64I-CCMOV-NEXT: lw a2, 0(a1) 182; RV64I-CCMOV-NEXT: sltu a5, a3, a0 183; RV64I-CCMOV-NEXT: mips.ccmov a0, a5, a3, a0 184; RV64I-CCMOV-NEXT: lw a3, 0(a1) 185; RV64I-CCMOV-NEXT: sext.w a5, a0 186; RV64I-CCMOV-NEXT: slt a5, a4, a5 187; RV64I-CCMOV-NEXT: mips.ccmov a0, a5, a0, a4 188; RV64I-CCMOV-NEXT: lw a4, 0(a1) 189; RV64I-CCMOV-NEXT: sext.w a5, a0 190; RV64I-CCMOV-NEXT: slt a5, a5, a2 191; RV64I-CCMOV-NEXT: mips.ccmov a0, a5, a2, a0 192; RV64I-CCMOV-NEXT: lw a2, 0(a1) 193; RV64I-CCMOV-NEXT: sext.w a5, a0 194; RV64I-CCMOV-NEXT: slt a5, a5, a3 195; RV64I-CCMOV-NEXT: mips.ccmov a0, a5, a0, a3 196; RV64I-CCMOV-NEXT: lw a3, 0(a1) 197; RV64I-CCMOV-NEXT: sext.w a5, a0 198; RV64I-CCMOV-NEXT: slt a5, a4, a5 199; RV64I-CCMOV-NEXT: mips.ccmov a0, a5, a4, a0 200; RV64I-CCMOV-NEXT: lw a4, 0(a1) 201; RV64I-CCMOV-NEXT: slti a5, a2, 1 202; RV64I-CCMOV-NEXT: mips.ccmov a0, a5, a0, a2 203; RV64I-CCMOV-NEXT: slti a5, a2, 0 204; RV64I-CCMOV-NEXT: mips.ccmov a0, a5, a3, a0 205; RV64I-CCMOV-NEXT: lw a1, 0(a1) 206; RV64I-CCMOV-NEXT: slti a3, a4, 1025 207; RV64I-CCMOV-NEXT: mips.ccmov a0, a3, a4, a0 208; RV64I-CCMOV-NEXT: sltiu a2, a2, 2047 209; RV64I-CCMOV-NEXT: mips.ccmov a0, a2, a1, a0 210; RV64I-CCMOV-NEXT: sext.w a0, a0 211; RV64I-CCMOV-NEXT: ret 212 %val1 = load volatile i32, ptr %b 213 %tst1 = icmp eq i32 %a, %val1 214 %val2 = select i1 %tst1, i32 %a, i32 %val1 215 216 %val3 = load volatile i32, ptr %b 217 %tst2 = icmp ne i32 %val2, %val3 218 %val4 = select i1 %tst2, i32 %val2, i32 %val3 219 220 %val5 = load volatile i32, ptr %b 221 %tst3 = icmp ugt i32 %val4, %val5 222 %val6 = select i1 %tst3, i32 %val4, i32 %val5 223 224 %val7 = load volatile i32, ptr %b 225 %tst4 = icmp uge i32 %val6, %val7 226 %val8 = select i1 %tst4, i32 %val6, i32 %val7 227 228 %val9 = load volatile i32, ptr %b 229 %tst5 = icmp ult i32 %val8, %val9 230 %val10 = select i1 %tst5, i32 %val8, i32 %val9 231 232 %val11 = load volatile i32, ptr %b 233 %tst6 = icmp ule i32 %val10, %val11 234 %val12 = select i1 %tst6, i32 %val10, i32 %val11 235 236 %val13 = load volatile i32, ptr %b 237 %tst7 = icmp sgt i32 %val12, %val13 238 %val14 = select i1 %tst7, i32 %val12, i32 %val13 239 240 %val15 = load volatile i32, ptr %b 241 %tst8 = icmp sge i32 %val14, %val15 242 %val16 = select i1 %tst8, i32 %val14, i32 %val15 243 244 %val17 = load volatile i32, ptr %b 245 %tst9 = icmp slt i32 %val16, %val17 246 %val18 = select i1 %tst9, i32 %val16, i32 %val17 247 248 %val19 = load volatile i32, ptr %b 249 %tst10 = icmp sle i32 %val18, %val19 250 %val20 = select i1 %tst10, i32 %val18, i32 %val19 251 252 %val21 = load volatile i32, ptr %b 253 %tst11 = icmp slt i32 %val21, 1 254 %val22 = select i1 %tst11, i32 %val20, i32 %val21 255 256 %val23 = load volatile i32, ptr %b 257 %tst12 = icmp sgt i32 %val21, -1 258 %val24 = select i1 %tst12, i32 %val22, i32 %val23 259 260 %val25 = load volatile i32, ptr %b 261 %tst13 = icmp sgt i32 %val25, 1024 262 %val26 = select i1 %tst13, i32 %val24, i32 %val25 263 264 %val27 = load volatile i32, ptr %b 265 %tst14 = icmp ugt i32 %val21, 2046 266 %val28 = select i1 %tst14, i32 %val26, i32 %val27 267 ret i32 %val28 268} 269 270; Test that we can ComputeNumSignBits across basic blocks when the live out is 271; RISCVISD::SELECT_CC. There should be no slli+srai or sext.h in the output. 272define signext i16 @numsignbits(i16 signext %0, i16 signext %1, i16 signext %2, i16 signext %3) nounwind { 273; RV32I-LABEL: numsignbits: 274; RV32I: # %bb.0: 275; RV32I-NEXT: addi sp, sp, -16 276; RV32I-NEXT: sw ra, 12(sp) # 4-byte Folded Spill 277; RV32I-NEXT: sw s0, 8(sp) # 4-byte Folded Spill 278; RV32I-NEXT: mv s0, a3 279; RV32I-NEXT: beqz a0, .LBB1_2 280; RV32I-NEXT: # %bb.1: 281; RV32I-NEXT: mv s0, a2 282; RV32I-NEXT: .LBB1_2: 283; RV32I-NEXT: beqz a1, .LBB1_4 284; RV32I-NEXT: # %bb.3: 285; RV32I-NEXT: mv a0, s0 286; RV32I-NEXT: call bar 287; RV32I-NEXT: .LBB1_4: 288; RV32I-NEXT: mv a0, s0 289; RV32I-NEXT: lw ra, 12(sp) # 4-byte Folded Reload 290; RV32I-NEXT: lw s0, 8(sp) # 4-byte Folded Reload 291; RV32I-NEXT: addi sp, sp, 16 292; RV32I-NEXT: ret 293; 294; RV64I-LABEL: numsignbits: 295; RV64I: # %bb.0: 296; RV64I-NEXT: addi sp, sp, -16 297; RV64I-NEXT: sd ra, 8(sp) # 8-byte Folded Spill 298; RV64I-NEXT: sd s0, 0(sp) # 8-byte Folded Spill 299; RV64I-NEXT: mv s0, a3 300; RV64I-NEXT: beqz a0, .LBB1_2 301; RV64I-NEXT: # %bb.1: 302; RV64I-NEXT: mv s0, a2 303; RV64I-NEXT: .LBB1_2: 304; RV64I-NEXT: beqz a1, .LBB1_4 305; RV64I-NEXT: # %bb.3: 306; RV64I-NEXT: mv a0, s0 307; RV64I-NEXT: call bar 308; RV64I-NEXT: .LBB1_4: 309; RV64I-NEXT: mv a0, s0 310; RV64I-NEXT: ld ra, 8(sp) # 8-byte Folded Reload 311; RV64I-NEXT: ld s0, 0(sp) # 8-byte Folded Reload 312; RV64I-NEXT: addi sp, sp, 16 313; RV64I-NEXT: ret 314; 315; RV64I-CCMOV-LABEL: numsignbits: 316; RV64I-CCMOV: # %bb.0: 317; RV64I-CCMOV-NEXT: addi sp, sp, -16 318; RV64I-CCMOV-NEXT: sd ra, 8(sp) # 8-byte Folded Spill 319; RV64I-CCMOV-NEXT: sd s0, 0(sp) # 8-byte Folded Spill 320; RV64I-CCMOV-NEXT: mips.ccmov s0, a0, a2, a3 321; RV64I-CCMOV-NEXT: beqz a1, .LBB1_2 322; RV64I-CCMOV-NEXT: # %bb.1: 323; RV64I-CCMOV-NEXT: mv a0, s0 324; RV64I-CCMOV-NEXT: call bar 325; RV64I-CCMOV-NEXT: .LBB1_2: 326; RV64I-CCMOV-NEXT: mv a0, s0 327; RV64I-CCMOV-NEXT: ld ra, 8(sp) # 8-byte Folded Reload 328; RV64I-CCMOV-NEXT: ld s0, 0(sp) # 8-byte Folded Reload 329; RV64I-CCMOV-NEXT: addi sp, sp, 16 330; RV64I-CCMOV-NEXT: ret 331 %5 = icmp eq i16 %0, 0 332 %6 = select i1 %5, i16 %3, i16 %2 333 %7 = icmp eq i16 %1, 0 334 br i1 %7, label %9, label %8 335 3368: ; preds = %4 337 tail call void @bar(i16 signext %6) 338 br label %9 339 3409: ; preds = %8, %4 341 ret i16 %6 342} 343 344declare void @bar(i16 signext) 345 346define i32 @select_sge_int16min(i32 signext %x, i32 signext %y, i32 signext %z) { 347; RV32I-LABEL: select_sge_int16min: 348; RV32I: # %bb.0: 349; RV32I-NEXT: lui a3, 1048560 350; RV32I-NEXT: addi a3, a3, -1 351; RV32I-NEXT: blt a3, a0, .LBB2_2 352; RV32I-NEXT: # %bb.1: 353; RV32I-NEXT: mv a1, a2 354; RV32I-NEXT: .LBB2_2: 355; RV32I-NEXT: mv a0, a1 356; RV32I-NEXT: ret 357; 358; RV64I-LABEL: select_sge_int16min: 359; RV64I: # %bb.0: 360; RV64I-NEXT: lui a3, 1048560 361; RV64I-NEXT: addiw a3, a3, -1 362; RV64I-NEXT: blt a3, a0, .LBB2_2 363; RV64I-NEXT: # %bb.1: 364; RV64I-NEXT: mv a1, a2 365; RV64I-NEXT: .LBB2_2: 366; RV64I-NEXT: mv a0, a1 367; RV64I-NEXT: ret 368; 369; RV64I-CCMOV-LABEL: select_sge_int16min: 370; RV64I-CCMOV: # %bb.0: 371; RV64I-CCMOV-NEXT: lui a3, 1048560 372; RV64I-CCMOV-NEXT: addiw a3, a3, -1 373; RV64I-CCMOV-NEXT: slt a0, a3, a0 374; RV64I-CCMOV-NEXT: mips.ccmov a0, a0, a1, a2 375; RV64I-CCMOV-NEXT: ret 376 %a = icmp sge i32 %x, -65536 377 %b = select i1 %a, i32 %y, i32 %z 378 ret i32 %b 379} 380 381define i64 @select_sge_int32min(i64 %x, i64 %y, i64 %z) { 382; RV32I-LABEL: select_sge_int32min: 383; RV32I: # %bb.0: 384; RV32I-NEXT: li a6, -1 385; RV32I-NEXT: bne a1, a6, .LBB3_2 386; RV32I-NEXT: # %bb.1: 387; RV32I-NEXT: slti a0, a0, 0 388; RV32I-NEXT: j .LBB3_3 389; RV32I-NEXT: .LBB3_2: 390; RV32I-NEXT: slti a0, a1, 0 391; RV32I-NEXT: xori a0, a0, 1 392; RV32I-NEXT: .LBB3_3: 393; RV32I-NEXT: bnez a0, .LBB3_5 394; RV32I-NEXT: # %bb.4: 395; RV32I-NEXT: mv a2, a4 396; RV32I-NEXT: mv a3, a5 397; RV32I-NEXT: .LBB3_5: 398; RV32I-NEXT: mv a0, a2 399; RV32I-NEXT: mv a1, a3 400; RV32I-NEXT: ret 401; 402; RV64I-LABEL: select_sge_int32min: 403; RV64I: # %bb.0: 404; RV64I-NEXT: lui a3, 524288 405; RV64I-NEXT: addi a3, a3, -1 406; RV64I-NEXT: blt a3, a0, .LBB3_2 407; RV64I-NEXT: # %bb.1: 408; RV64I-NEXT: mv a1, a2 409; RV64I-NEXT: .LBB3_2: 410; RV64I-NEXT: mv a0, a1 411; RV64I-NEXT: ret 412; 413; RV64I-CCMOV-LABEL: select_sge_int32min: 414; RV64I-CCMOV: # %bb.0: 415; RV64I-CCMOV-NEXT: lui a3, 524288 416; RV64I-CCMOV-NEXT: addi a3, a3, -1 417; RV64I-CCMOV-NEXT: slt a0, a3, a0 418; RV64I-CCMOV-NEXT: mips.ccmov a0, a0, a1, a2 419; RV64I-CCMOV-NEXT: ret 420 %a = icmp sge i64 %x, -2147483648 421 %b = select i1 %a, i64 %y, i64 %z 422 ret i64 %b 423} 424