1; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py 2; RUN: llc -mtriple=riscv32 -verify-machineinstrs < %s \ 3; RUN: | FileCheck -check-prefix=RV32I %s 4; RUN: llc -mtriple=riscv32 -mattr=+experimental-zbt -verify-machineinstrs < %s \ 5; RUN: | FileCheck -check-prefix=RV32IBT %s 6; RUN: llc -mtriple=riscv64 -verify-machineinstrs < %s \ 7; RUN: | FileCheck -check-prefix=RV64I %s 8; RUN: llc -mtriple=riscv64 -mattr=+experimental-zbt -verify-machineinstrs < %s \ 9; RUN: | FileCheck -check-prefix=RV64IBT %s 10 11;; There are a few different ways to lower (select (or A, B), X, Y). This test 12;; ensures that we do so with as few branches as possible. 13 14define signext i32 @select_of_or(i1 zeroext %a, i1 zeroext %b, i32 signext %c, i32 signext %d) nounwind { 15; RV32I-LABEL: select_of_or: 16; RV32I: # %bb.0: 17; RV32I-NEXT: or a1, a0, a1 18; RV32I-NEXT: mv a0, a2 19; RV32I-NEXT: bnez a1, .LBB0_2 20; RV32I-NEXT: # %bb.1: 21; RV32I-NEXT: mv a0, a3 22; RV32I-NEXT: .LBB0_2: 23; RV32I-NEXT: ret 24; 25; RV32IBT-LABEL: select_of_or: 26; RV32IBT: # %bb.0: 27; RV32IBT-NEXT: or a0, a0, a1 28; RV32IBT-NEXT: cmov a0, a0, a2, a3 29; RV32IBT-NEXT: ret 30; 31; RV64I-LABEL: select_of_or: 32; RV64I: # %bb.0: 33; RV64I-NEXT: or a1, a0, a1 34; RV64I-NEXT: mv a0, a2 35; RV64I-NEXT: bnez a1, .LBB0_2 36; RV64I-NEXT: # %bb.1: 37; RV64I-NEXT: mv a0, a3 38; RV64I-NEXT: .LBB0_2: 39; RV64I-NEXT: ret 40; 41; RV64IBT-LABEL: select_of_or: 42; RV64IBT: # %bb.0: 43; RV64IBT-NEXT: or a0, a0, a1 44; RV64IBT-NEXT: cmov a0, a0, a2, a3 45; RV64IBT-NEXT: ret 46 %1 = or i1 %a, %b 47 %2 = select i1 %1, i32 %c, i32 %d 48 ret i32 %2 49} 50 51declare signext i32 @either() nounwind 52declare signext i32 @neither() nounwind 53 54define signext i32 @if_of_or(i1 zeroext %a, i1 zeroext %b) nounwind { 55; RV32I-LABEL: if_of_or: 56; RV32I: # %bb.0: 57; RV32I-NEXT: addi sp, sp, -16 58; RV32I-NEXT: sw ra, 12(sp) # 4-byte Folded Spill 59; RV32I-NEXT: or a0, a0, a1 60; RV32I-NEXT: beqz a0, .LBB1_2 61; RV32I-NEXT: # %bb.1: # %if.then 62; RV32I-NEXT: call either@plt 63; RV32I-NEXT: j .LBB1_3 64; RV32I-NEXT: .LBB1_2: # %if.else 65; RV32I-NEXT: call neither@plt 66; RV32I-NEXT: .LBB1_3: # %if.end 67; RV32I-NEXT: lw ra, 12(sp) # 4-byte Folded Reload 68; RV32I-NEXT: addi sp, sp, 16 69; RV32I-NEXT: ret 70; 71; RV32IBT-LABEL: if_of_or: 72; RV32IBT: # %bb.0: 73; RV32IBT-NEXT: addi sp, sp, -16 74; RV32IBT-NEXT: sw ra, 12(sp) # 4-byte Folded Spill 75; RV32IBT-NEXT: or a0, a0, a1 76; RV32IBT-NEXT: beqz a0, .LBB1_2 77; RV32IBT-NEXT: # %bb.1: # %if.then 78; RV32IBT-NEXT: call either@plt 79; RV32IBT-NEXT: j .LBB1_3 80; RV32IBT-NEXT: .LBB1_2: # %if.else 81; RV32IBT-NEXT: call neither@plt 82; RV32IBT-NEXT: .LBB1_3: # %if.end 83; RV32IBT-NEXT: lw ra, 12(sp) # 4-byte Folded Reload 84; RV32IBT-NEXT: addi sp, sp, 16 85; RV32IBT-NEXT: ret 86; 87; RV64I-LABEL: if_of_or: 88; RV64I: # %bb.0: 89; RV64I-NEXT: addi sp, sp, -16 90; RV64I-NEXT: sd ra, 8(sp) # 8-byte Folded Spill 91; RV64I-NEXT: or a0, a0, a1 92; RV64I-NEXT: beqz a0, .LBB1_2 93; RV64I-NEXT: # %bb.1: # %if.then 94; RV64I-NEXT: call either@plt 95; RV64I-NEXT: j .LBB1_3 96; RV64I-NEXT: .LBB1_2: # %if.else 97; RV64I-NEXT: call neither@plt 98; RV64I-NEXT: .LBB1_3: # %if.end 99; RV64I-NEXT: ld ra, 8(sp) # 8-byte Folded Reload 100; RV64I-NEXT: addi sp, sp, 16 101; RV64I-NEXT: ret 102; 103; RV64IBT-LABEL: if_of_or: 104; RV64IBT: # %bb.0: 105; RV64IBT-NEXT: addi sp, sp, -16 106; RV64IBT-NEXT: sd ra, 8(sp) # 8-byte Folded Spill 107; RV64IBT-NEXT: or a0, a0, a1 108; RV64IBT-NEXT: beqz a0, .LBB1_2 109; RV64IBT-NEXT: # %bb.1: # %if.then 110; RV64IBT-NEXT: call either@plt 111; RV64IBT-NEXT: j .LBB1_3 112; RV64IBT-NEXT: .LBB1_2: # %if.else 113; RV64IBT-NEXT: call neither@plt 114; RV64IBT-NEXT: .LBB1_3: # %if.end 115; RV64IBT-NEXT: ld ra, 8(sp) # 8-byte Folded Reload 116; RV64IBT-NEXT: addi sp, sp, 16 117; RV64IBT-NEXT: ret 118 %1 = or i1 %a, %b 119 br i1 %1, label %if.then, label %if.else 120 121if.then: 122 %2 = tail call i32 @either() 123 br label %if.end 124 125if.else: 126 %3 = tail call i32 @neither() 127 br label %if.end 128 129if.end: 130 %4 = phi i32 [%2, %if.then], [%3, %if.else] 131 ret i32 %4 132} 133