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-prefix=RV32I %s 4; RUN: llc -mtriple=riscv32 -mattr=+experimental-zbt -disable-block-placement -verify-machineinstrs < %s \ 5; RUN: | FileCheck -check-prefix=RV32IBT %s 6 7define signext i32 @foo(i32 signext %a, i32 *%b) nounwind { 8; RV32I-LABEL: foo: 9; RV32I: # %bb.0: 10; RV32I-NEXT: lw a2, 0(a1) 11; RV32I-NEXT: beq a0, a2, .LBB0_2 12; RV32I-NEXT: # %bb.1: 13; RV32I-NEXT: mv a0, a2 14; RV32I-NEXT: .LBB0_2: 15; RV32I-NEXT: lw a2, 0(a1) 16; RV32I-NEXT: bne a0, a2, .LBB0_4 17; RV32I-NEXT: # %bb.3: 18; RV32I-NEXT: mv a0, a2 19; RV32I-NEXT: .LBB0_4: 20; RV32I-NEXT: lw a2, 0(a1) 21; RV32I-NEXT: bltu a2, a0, .LBB0_6 22; RV32I-NEXT: # %bb.5: 23; RV32I-NEXT: mv a0, a2 24; RV32I-NEXT: .LBB0_6: 25; RV32I-NEXT: lw a2, 0(a1) 26; RV32I-NEXT: bgeu a0, a2, .LBB0_8 27; RV32I-NEXT: # %bb.7: 28; RV32I-NEXT: mv a0, a2 29; RV32I-NEXT: .LBB0_8: 30; RV32I-NEXT: lw a2, 0(a1) 31; RV32I-NEXT: bltu a0, a2, .LBB0_10 32; RV32I-NEXT: # %bb.9: 33; RV32I-NEXT: mv a0, a2 34; RV32I-NEXT: .LBB0_10: 35; RV32I-NEXT: lw a2, 0(a1) 36; RV32I-NEXT: bgeu a2, a0, .LBB0_12 37; RV32I-NEXT: # %bb.11: 38; RV32I-NEXT: mv a0, a2 39; RV32I-NEXT: .LBB0_12: 40; RV32I-NEXT: lw a2, 0(a1) 41; RV32I-NEXT: blt a2, a0, .LBB0_14 42; RV32I-NEXT: # %bb.13: 43; RV32I-NEXT: mv a0, a2 44; RV32I-NEXT: .LBB0_14: 45; RV32I-NEXT: lw a2, 0(a1) 46; RV32I-NEXT: bge a0, a2, .LBB0_16 47; RV32I-NEXT: # %bb.15: 48; RV32I-NEXT: mv a0, a2 49; RV32I-NEXT: .LBB0_16: 50; RV32I-NEXT: lw a2, 0(a1) 51; RV32I-NEXT: blt a0, a2, .LBB0_18 52; RV32I-NEXT: # %bb.17: 53; RV32I-NEXT: mv a0, a2 54; RV32I-NEXT: .LBB0_18: 55; RV32I-NEXT: lw a2, 0(a1) 56; RV32I-NEXT: bge a2, a0, .LBB0_20 57; RV32I-NEXT: # %bb.19: 58; RV32I-NEXT: mv a0, a2 59; RV32I-NEXT: .LBB0_20: 60; RV32I-NEXT: lw a2, 0(a1) 61; RV32I-NEXT: blez a2, .LBB0_22 62; RV32I-NEXT: # %bb.21: 63; RV32I-NEXT: mv a0, a2 64; RV32I-NEXT: .LBB0_22: 65; RV32I-NEXT: lw a1, 0(a1) 66; RV32I-NEXT: bgez a2, .LBB0_24 67; RV32I-NEXT: # %bb.23: 68; RV32I-NEXT: mv a0, a1 69; RV32I-NEXT: .LBB0_24: 70; RV32I-NEXT: ret 71; 72; RV32IBT-LABEL: foo: 73; RV32IBT: # %bb.0: 74; RV32IBT-NEXT: lw a2, 0(a1) 75; RV32IBT-NEXT: lw a3, 0(a1) 76; RV32IBT-NEXT: xor a4, a0, a2 77; RV32IBT-NEXT: cmov a0, a4, a2, a0 78; RV32IBT-NEXT: lw a2, 0(a1) 79; RV32IBT-NEXT: xor a4, a0, a3 80; RV32IBT-NEXT: cmov a0, a4, a0, a3 81; RV32IBT-NEXT: lw a3, 0(a1) 82; RV32IBT-NEXT: sltu a4, a2, a0 83; RV32IBT-NEXT: cmov a0, a4, a0, a2 84; RV32IBT-NEXT: lw a2, 0(a1) 85; RV32IBT-NEXT: sltu a4, a0, a3 86; RV32IBT-NEXT: cmov a0, a4, a3, a0 87; RV32IBT-NEXT: lw a3, 0(a1) 88; RV32IBT-NEXT: sltu a4, a0, a2 89; RV32IBT-NEXT: cmov a0, a4, a0, a2 90; RV32IBT-NEXT: lw a2, 0(a1) 91; RV32IBT-NEXT: sltu a4, a3, a0 92; RV32IBT-NEXT: cmov a0, a4, a3, a0 93; RV32IBT-NEXT: lw a3, 0(a1) 94; RV32IBT-NEXT: slt a4, a2, a0 95; RV32IBT-NEXT: cmov a0, a4, a0, a2 96; RV32IBT-NEXT: lw a2, 0(a1) 97; RV32IBT-NEXT: slt a4, a0, a3 98; RV32IBT-NEXT: cmov a0, a4, a3, a0 99; RV32IBT-NEXT: lw a3, 0(a1) 100; RV32IBT-NEXT: slt a4, a0, a2 101; RV32IBT-NEXT: lw a5, 0(a1) 102; RV32IBT-NEXT: cmov a0, a4, a0, a2 103; RV32IBT-NEXT: slt a2, a3, a0 104; RV32IBT-NEXT: cmov a0, a2, a3, a0 105; RV32IBT-NEXT: slti a2, a5, 1 106; RV32IBT-NEXT: lw a1, 0(a1) 107; RV32IBT-NEXT: cmov a0, a2, a0, a5 108; RV32IBT-NEXT: li a2, -1 109; RV32IBT-NEXT: slt a2, a2, a5 110; RV32IBT-NEXT: cmov a0, a2, a0, a1 111; RV32IBT-NEXT: ret 112 %val1 = load volatile i32, i32* %b 113 %tst1 = icmp eq i32 %a, %val1 114 %val2 = select i1 %tst1, i32 %a, i32 %val1 115 116 %val3 = load volatile i32, i32* %b 117 %tst2 = icmp ne i32 %val2, %val3 118 %val4 = select i1 %tst2, i32 %val2, i32 %val3 119 120 %val5 = load volatile i32, i32* %b 121 %tst3 = icmp ugt i32 %val4, %val5 122 %val6 = select i1 %tst3, i32 %val4, i32 %val5 123 124 %val7 = load volatile i32, i32* %b 125 %tst4 = icmp uge i32 %val6, %val7 126 %val8 = select i1 %tst4, i32 %val6, i32 %val7 127 128 %val9 = load volatile i32, i32* %b 129 %tst5 = icmp ult i32 %val8, %val9 130 %val10 = select i1 %tst5, i32 %val8, i32 %val9 131 132 %val11 = load volatile i32, i32* %b 133 %tst6 = icmp ule i32 %val10, %val11 134 %val12 = select i1 %tst6, i32 %val10, i32 %val11 135 136 %val13 = load volatile i32, i32* %b 137 %tst7 = icmp sgt i32 %val12, %val13 138 %val14 = select i1 %tst7, i32 %val12, i32 %val13 139 140 %val15 = load volatile i32, i32* %b 141 %tst8 = icmp sge i32 %val14, %val15 142 %val16 = select i1 %tst8, i32 %val14, i32 %val15 143 144 %val17 = load volatile i32, i32* %b 145 %tst9 = icmp slt i32 %val16, %val17 146 %val18 = select i1 %tst9, i32 %val16, i32 %val17 147 148 %val19 = load volatile i32, i32* %b 149 %tst10 = icmp sle i32 %val18, %val19 150 %val20 = select i1 %tst10, i32 %val18, i32 %val19 151 152 %val21 = load volatile i32, i32* %b 153 %tst11 = icmp slt i32 %val21, 1 154 %val22 = select i1 %tst11, i32 %val20, i32 %val21 155 156 %val23 = load volatile i32, i32* %b 157 %tst12 = icmp sgt i32 %val21, -1 158 %val24 = select i1 %tst12, i32 %val22, i32 %val23 159 160 ret i32 %val24 161} 162 163; Test that we can ComputeNumSignBits across basic blocks when the live out is 164; RISCVISD::SELECT_CC. There should be no slli+srai or sext.h in the output. 165define signext i16 @numsignbits(i16 signext %0, i16 signext %1, i16 signext %2, i16 signext %3) nounwind { 166; RV32I-LABEL: numsignbits: 167; RV32I: # %bb.0: 168; RV32I-NEXT: addi sp, sp, -16 169; RV32I-NEXT: sw ra, 12(sp) # 4-byte Folded Spill 170; RV32I-NEXT: sw s0, 8(sp) # 4-byte Folded Spill 171; RV32I-NEXT: mv s0, a3 172; RV32I-NEXT: beqz a0, .LBB1_2 173; RV32I-NEXT: # %bb.1: 174; RV32I-NEXT: mv s0, a2 175; RV32I-NEXT: .LBB1_2: 176; RV32I-NEXT: beqz a1, .LBB1_4 177; RV32I-NEXT: # %bb.3: 178; RV32I-NEXT: mv a0, s0 179; RV32I-NEXT: call bar@plt 180; RV32I-NEXT: .LBB1_4: 181; RV32I-NEXT: mv a0, s0 182; RV32I-NEXT: lw ra, 12(sp) # 4-byte Folded Reload 183; RV32I-NEXT: lw s0, 8(sp) # 4-byte Folded Reload 184; RV32I-NEXT: addi sp, sp, 16 185; RV32I-NEXT: ret 186; 187; RV32IBT-LABEL: numsignbits: 188; RV32IBT: # %bb.0: 189; RV32IBT-NEXT: addi sp, sp, -16 190; RV32IBT-NEXT: sw ra, 12(sp) # 4-byte Folded Spill 191; RV32IBT-NEXT: sw s0, 8(sp) # 4-byte Folded Spill 192; RV32IBT-NEXT: cmov s0, a0, a2, a3 193; RV32IBT-NEXT: beqz a1, .LBB1_2 194; RV32IBT-NEXT: # %bb.1: 195; RV32IBT-NEXT: mv a0, s0 196; RV32IBT-NEXT: call bar@plt 197; RV32IBT-NEXT: .LBB1_2: 198; RV32IBT-NEXT: mv a0, s0 199; RV32IBT-NEXT: lw ra, 12(sp) # 4-byte Folded Reload 200; RV32IBT-NEXT: lw s0, 8(sp) # 4-byte Folded Reload 201; RV32IBT-NEXT: addi sp, sp, 16 202; RV32IBT-NEXT: ret 203 %5 = icmp eq i16 %0, 0 204 %6 = select i1 %5, i16 %3, i16 %2 205 %7 = icmp eq i16 %1, 0 206 br i1 %7, label %9, label %8 207 2088: ; preds = %4 209 tail call void @bar(i16 signext %6) 210 br label %9 211 2129: ; preds = %8, %4 213 ret i16 %6 214} 215 216declare void @bar(i16 signext) 217