1; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py 2; RUN: llc -mtriple=riscv32 -verify-machineinstrs < %s \ 3; RUN: | FileCheck %s -check-prefixes=RV32 4; RUN: llc -mtriple=riscv64 -verify-machineinstrs < %s \ 5; RUN: | FileCheck %s -check-prefixes=RV64 6 7define i32 @optbranch_32(i32 %Arg) { 8; RV32-LABEL: optbranch_32: 9; RV32: # %bb.0: # %bb 10; RV32-NEXT: addi a0, a0, 1 11; RV32-NEXT: bnez a0, .LBB0_2 12; RV32-NEXT: # %bb.1: # %bb2 13; RV32-NEXT: li a0, -1 14; RV32-NEXT: .LBB0_2: # %bb3 15; RV32-NEXT: ret 16; 17; RV64-LABEL: optbranch_32: 18; RV64: # %bb.0: # %bb 19; RV64-NEXT: addiw a0, a0, 1 20; RV64-NEXT: bnez a0, .LBB0_2 21; RV64-NEXT: # %bb.1: # %bb2 22; RV64-NEXT: li a0, -1 23; RV64-NEXT: .LBB0_2: # %bb3 24; RV64-NEXT: ret 25bb: 26 %i1 = icmp eq i32 %Arg, -1 27 br i1 %i1, label %bb2, label %bb3 28 29bb2: 30 ret i32 -1 31 32bb3: 33 %i4 = add nuw i32 %Arg, 1 34 ret i32 %i4 35} 36 37define i64 @optbranch_64(i64 %Arg) { 38; RV32-LABEL: optbranch_64: 39; RV32: # %bb.0: # %bb 40; RV32-NEXT: addi a0, a0, 1 41; RV32-NEXT: seqz a2, a0 42; RV32-NEXT: add a1, a1, a2 43; RV32-NEXT: or a2, a0, a1 44; RV32-NEXT: bnez a2, .LBB1_2 45; RV32-NEXT: # %bb.1: # %bb2 46; RV32-NEXT: li a0, -1 47; RV32-NEXT: li a1, -1 48; RV32-NEXT: .LBB1_2: # %bb3 49; RV32-NEXT: ret 50; 51; RV64-LABEL: optbranch_64: 52; RV64: # %bb.0: # %bb 53; RV64-NEXT: addi a0, a0, 1 54; RV64-NEXT: bnez a0, .LBB1_2 55; RV64-NEXT: # %bb.1: # %bb2 56; RV64-NEXT: li a0, -1 57; RV64-NEXT: .LBB1_2: # %bb3 58; RV64-NEXT: ret 59bb: 60 %i1 = icmp eq i64 %Arg, -1 61 br i1 %i1, label %bb2, label %bb3 62 63bb2: 64 ret i64 -1 65 66bb3: 67 %i4 = add nuw i64 %Arg, 1 68 ret i64 %i4 69} 70 71define i32 @test_lshr(i32 %v) { 72; RV32-LABEL: test_lshr: 73; RV32: # %bb.0: # %entry 74; RV32-NEXT: li a1, 0 75; RV32-NEXT: beqz a0, .LBB2_2 76; RV32-NEXT: .LBB2_1: # %for.body 77; RV32-NEXT: # =>This Inner Loop Header: Depth=1 78; RV32-NEXT: andi a2, a0, 1 79; RV32-NEXT: srli a0, a0, 1 80; RV32-NEXT: add a1, a1, a2 81; RV32-NEXT: bnez a0, .LBB2_1 82; RV32-NEXT: .LBB2_2: # %for.end 83; RV32-NEXT: mv a0, a1 84; RV32-NEXT: ret 85; 86; RV64-LABEL: test_lshr: 87; RV64: # %bb.0: # %entry 88; RV64-NEXT: sext.w a1, a0 89; RV64-NEXT: beqz a1, .LBB2_3 90; RV64-NEXT: # %bb.1: # %for.body.preheader 91; RV64-NEXT: li a1, 0 92; RV64-NEXT: .LBB2_2: # %for.body 93; RV64-NEXT: # =>This Inner Loop Header: Depth=1 94; RV64-NEXT: andi a2, a0, 1 95; RV64-NEXT: srliw a0, a0, 1 96; RV64-NEXT: addw a1, a1, a2 97; RV64-NEXT: bnez a0, .LBB2_2 98; RV64-NEXT: .LBB2_3: # %for.end 99; RV64-NEXT: mv a0, a1 100; RV64-NEXT: ret 101entry: 102 %tobool.not4 = icmp eq i32 %v, 0 103 br i1 %tobool.not4, label %for.end, label %for.body 104 105for.body: ; preds = %entry, %for.body 106 %c.06 = phi i32 [ %add, %for.body ], [ 0, %entry ] 107 %v.addr.05 = phi i32 [ %shr, %for.body ], [ %v, %entry ] 108 %and = and i32 %v.addr.05, 1 109 %add = add i32 %c.06, %and 110 %shr = lshr i32 %v.addr.05, 1 111 %tobool.not = icmp ult i32 %v.addr.05, 2 112 br i1 %tobool.not, label %for.end, label %for.body 113 114for.end: ; preds = %for.body, %entry 115 %c.0.lcssa = phi i32 [ 0, %entry ], [ %add, %for.body ] 116 ret i32 %c.0.lcssa 117} 118 119define i32 @test_lshr2(ptr nocapture %x, ptr nocapture readonly %y, i32 %n) { 120; RV32-LABEL: test_lshr2: 121; RV32: # %bb.0: # %entry 122; RV32-NEXT: srli a2, a2, 2 123; RV32-NEXT: beqz a2, .LBB3_3 124; RV32-NEXT: # %bb.1: # %while.body.preheader 125; RV32-NEXT: slli a2, a2, 2 126; RV32-NEXT: add a2, a1, a2 127; RV32-NEXT: .LBB3_2: # %while.body 128; RV32-NEXT: # =>This Inner Loop Header: Depth=1 129; RV32-NEXT: lw a3, 0(a1) 130; RV32-NEXT: addi a4, a1, 4 131; RV32-NEXT: slli a3, a3, 1 132; RV32-NEXT: addi a1, a0, 4 133; RV32-NEXT: sw a3, 0(a0) 134; RV32-NEXT: mv a0, a1 135; RV32-NEXT: mv a1, a4 136; RV32-NEXT: bne a4, a2, .LBB3_2 137; RV32-NEXT: .LBB3_3: # %while.end 138; RV32-NEXT: li a0, 0 139; RV32-NEXT: ret 140; 141; RV64-LABEL: test_lshr2: 142; RV64: # %bb.0: # %entry 143; RV64-NEXT: srliw a2, a2, 2 144; RV64-NEXT: beqz a2, .LBB3_3 145; RV64-NEXT: # %bb.1: # %while.body.preheader 146; RV64-NEXT: addi a2, a2, -1 147; RV64-NEXT: slli a2, a2, 32 148; RV64-NEXT: srli a2, a2, 30 149; RV64-NEXT: add a2, a2, a1 150; RV64-NEXT: addi a2, a2, 4 151; RV64-NEXT: .LBB3_2: # %while.body 152; RV64-NEXT: # =>This Inner Loop Header: Depth=1 153; RV64-NEXT: lw a3, 0(a1) 154; RV64-NEXT: addi a4, a1, 4 155; RV64-NEXT: slli a3, a3, 1 156; RV64-NEXT: addi a1, a0, 4 157; RV64-NEXT: sw a3, 0(a0) 158; RV64-NEXT: mv a0, a1 159; RV64-NEXT: mv a1, a4 160; RV64-NEXT: bne a4, a2, .LBB3_2 161; RV64-NEXT: .LBB3_3: # %while.end 162; RV64-NEXT: li a0, 0 163; RV64-NEXT: ret 164entry: 165 %tobool.not4 = icmp ult i32 %n, 4 166 br i1 %tobool.not4, label %while.end, label %while.body.preheader 167 168while.body.preheader: ; preds = %entry 169 %shr = lshr i32 %n, 2 170 br label %while.body 171 172while.body: ; preds = %while.body.preheader, %while.body 173 %c.07 = phi i32 [ %dec, %while.body ], [ %shr, %while.body.preheader ] 174 %x.addr.06 = phi ptr [ %incdec.ptr1, %while.body ], [ %x, %while.body.preheader ] 175 %y.addr.05 = phi ptr [ %incdec.ptr, %while.body ], [ %y, %while.body.preheader ] 176 %incdec.ptr = getelementptr inbounds i32, ptr %y.addr.05, i32 1 177 %0 = load i32, ptr %y.addr.05, align 4 178 %mul = shl nsw i32 %0, 1 179 %incdec.ptr1 = getelementptr inbounds i32, ptr %x.addr.06, i32 1 180 store i32 %mul, ptr %x.addr.06, align 4 181 %dec = add nsw i32 %c.07, -1 182 %tobool.not = icmp eq i32 %dec, 0 183 br i1 %tobool.not, label %while.end, label %while.body 184 185while.end: ; preds = %while.body, %entry 186 ret i32 0 187} 188