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-prefix=RV32I 4; RUN: llc -mtriple=riscv64 -verify-machineinstrs < %s \ 5; RUN: | FileCheck %s -check-prefix=RV64I 6 7define i32 @shl_by_complemented_32(i32 %x) { 8; RV32I-LABEL: shl_by_complemented_32: 9; RV32I: # %bb.0: 10; RV32I-NEXT: not a1, a0 11; RV32I-NEXT: sll a0, a0, a1 12; RV32I-NEXT: ret 13; 14; RV64I-LABEL: shl_by_complemented_32: 15; RV64I: # %bb.0: 16; RV64I-NEXT: not a1, a0 17; RV64I-NEXT: sllw a0, a0, a1 18; RV64I-NEXT: ret 19 %a = sub i32 31, %x 20 %b = shl i32 %x, %a 21 ret i32 %b 22} 23 24define i64 @shl_by_complemented_64(i64 %x) { 25; RV32I-LABEL: shl_by_complemented_64: 26; RV32I: # %bb.0: 27; RV32I-NEXT: not a4, a0 28; RV32I-NEXT: li a2, 31 29; RV32I-NEXT: sub a2, a2, a0 30; RV32I-NEXT: sll a3, a0, a4 31; RV32I-NEXT: bltz a2, .LBB1_2 32; RV32I-NEXT: # %bb.1: 33; RV32I-NEXT: mv a1, a3 34; RV32I-NEXT: j .LBB1_3 35; RV32I-NEXT: .LBB1_2: 36; RV32I-NEXT: sll a1, a1, a4 37; RV32I-NEXT: li a4, 63 38; RV32I-NEXT: sub a4, a4, a0 39; RV32I-NEXT: not a4, a4 40; RV32I-NEXT: srli a0, a0, 1 41; RV32I-NEXT: srl a0, a0, a4 42; RV32I-NEXT: or a1, a1, a0 43; RV32I-NEXT: .LBB1_3: 44; RV32I-NEXT: srai a0, a2, 31 45; RV32I-NEXT: and a0, a0, a3 46; RV32I-NEXT: ret 47; 48; RV64I-LABEL: shl_by_complemented_64: 49; RV64I: # %bb.0: 50; RV64I-NEXT: not a1, a0 51; RV64I-NEXT: sll a0, a0, a1 52; RV64I-NEXT: ret 53 %a = sub i64 63, %x 54 %b = shl i64 %x, %a 55 ret i64 %b 56} 57 58define i32 @lshr_by_complemented_32(i32 %x) { 59; RV32I-LABEL: lshr_by_complemented_32: 60; RV32I: # %bb.0: 61; RV32I-NEXT: not a1, a0 62; RV32I-NEXT: srl a0, a0, a1 63; RV32I-NEXT: ret 64; 65; RV64I-LABEL: lshr_by_complemented_32: 66; RV64I: # %bb.0: 67; RV64I-NEXT: not a1, a0 68; RV64I-NEXT: srlw a0, a0, a1 69; RV64I-NEXT: ret 70 %a = sub i32 31, %x 71 %b = lshr i32 %x, %a 72 ret i32 %b 73} 74 75define i64 @lshr_by_complemented_64(i64 %x) { 76; RV32I-LABEL: lshr_by_complemented_64: 77; RV32I: # %bb.0: 78; RV32I-NEXT: not a4, a0 79; RV32I-NEXT: li a2, 31 80; RV32I-NEXT: sub a2, a2, a0 81; RV32I-NEXT: srl a3, a1, a4 82; RV32I-NEXT: bltz a2, .LBB3_2 83; RV32I-NEXT: # %bb.1: 84; RV32I-NEXT: mv a0, a3 85; RV32I-NEXT: j .LBB3_3 86; RV32I-NEXT: .LBB3_2: 87; RV32I-NEXT: srl a4, a0, a4 88; RV32I-NEXT: li a5, 63 89; RV32I-NEXT: sub a5, a5, a0 90; RV32I-NEXT: not a0, a5 91; RV32I-NEXT: slli a1, a1, 1 92; RV32I-NEXT: sll a0, a1, a0 93; RV32I-NEXT: or a0, a4, a0 94; RV32I-NEXT: .LBB3_3: 95; RV32I-NEXT: srai a1, a2, 31 96; RV32I-NEXT: and a1, a1, a3 97; RV32I-NEXT: ret 98; 99; RV64I-LABEL: lshr_by_complemented_64: 100; RV64I: # %bb.0: 101; RV64I-NEXT: not a1, a0 102; RV64I-NEXT: srl a0, a0, a1 103; RV64I-NEXT: ret 104 %a = sub i64 63, %x 105 %b = lshr i64 %x, %a 106 ret i64 %b 107} 108 109define i32 @ashr_by_complemented_32(i32 %x) { 110; RV32I-LABEL: ashr_by_complemented_32: 111; RV32I: # %bb.0: 112; RV32I-NEXT: not a1, a0 113; RV32I-NEXT: sra a0, a0, a1 114; RV32I-NEXT: ret 115; 116; RV64I-LABEL: ashr_by_complemented_32: 117; RV64I: # %bb.0: 118; RV64I-NEXT: not a1, a0 119; RV64I-NEXT: sraw a0, a0, a1 120; RV64I-NEXT: ret 121 %a = sub i32 31, %x 122 %b = ashr i32 %x, %a 123 ret i32 %b 124} 125 126define i64 @ashr_by_complemented_64(i64 %x) { 127; RV32I-LABEL: ashr_by_complemented_64: 128; RV32I: # %bb.0: 129; RV32I-NEXT: mv a2, a0 130; RV32I-NEXT: li a0, 31 131; RV32I-NEXT: sub a4, a0, a2 132; RV32I-NEXT: not a3, a2 133; RV32I-NEXT: sra a0, a1, a3 134; RV32I-NEXT: bltz a4, .LBB5_2 135; RV32I-NEXT: # %bb.1: 136; RV32I-NEXT: srai a1, a1, 31 137; RV32I-NEXT: ret 138; RV32I-NEXT: .LBB5_2: 139; RV32I-NEXT: srl a3, a2, a3 140; RV32I-NEXT: li a4, 63 141; RV32I-NEXT: sub a4, a4, a2 142; RV32I-NEXT: not a2, a4 143; RV32I-NEXT: slli a1, a1, 1 144; RV32I-NEXT: sll a1, a1, a2 145; RV32I-NEXT: or a3, a3, a1 146; RV32I-NEXT: mv a1, a0 147; RV32I-NEXT: mv a0, a3 148; RV32I-NEXT: ret 149; 150; RV64I-LABEL: ashr_by_complemented_64: 151; RV64I: # %bb.0: 152; RV64I-NEXT: not a1, a0 153; RV64I-NEXT: sra a0, a0, a1 154; RV64I-NEXT: ret 155 %a = sub i64 63, %x 156 %b = ashr i64 %x, %a 157 ret i64 %b 158} 159 160define i32 @shl_by_masked_complemented_32(i32 %x) { 161; RV32I-LABEL: shl_by_masked_complemented_32: 162; RV32I: # %bb.0: 163; RV32I-NEXT: not a1, a0 164; RV32I-NEXT: sll a0, a0, a1 165; RV32I-NEXT: ret 166; 167; RV64I-LABEL: shl_by_masked_complemented_32: 168; RV64I: # %bb.0: 169; RV64I-NEXT: not a1, a0 170; RV64I-NEXT: sllw a0, a0, a1 171; RV64I-NEXT: ret 172 %a = sub i32 31, %x 173 %b = and i32 %a, 31 174 %c = shl i32 %x, %b 175 ret i32 %c 176} 177 178define i64 @shl_by_masked_complemented_64(i64 %x) { 179; RV32I-LABEL: shl_by_masked_complemented_64: 180; RV32I: # %bb.0: 181; RV32I-NEXT: li a2, 63 182; RV32I-NEXT: sub a2, a2, a0 183; RV32I-NEXT: andi a4, a2, 63 184; RV32I-NEXT: addi a2, a4, -32 185; RV32I-NEXT: not a3, a0 186; RV32I-NEXT: bltz a2, .LBB7_2 187; RV32I-NEXT: # %bb.1: 188; RV32I-NEXT: sll a1, a0, a4 189; RV32I-NEXT: j .LBB7_3 190; RV32I-NEXT: .LBB7_2: 191; RV32I-NEXT: sll a1, a1, a3 192; RV32I-NEXT: not a4, a4 193; RV32I-NEXT: srli a5, a0, 1 194; RV32I-NEXT: srl a4, a5, a4 195; RV32I-NEXT: or a1, a1, a4 196; RV32I-NEXT: .LBB7_3: 197; RV32I-NEXT: sll a0, a0, a3 198; RV32I-NEXT: srai a2, a2, 31 199; RV32I-NEXT: and a0, a2, a0 200; RV32I-NEXT: ret 201; 202; RV64I-LABEL: shl_by_masked_complemented_64: 203; RV64I: # %bb.0: 204; RV64I-NEXT: not a1, a0 205; RV64I-NEXT: sll a0, a0, a1 206; RV64I-NEXT: ret 207 %a = sub i64 63, %x 208 %b = and i64 %a, 63 209 %c = shl i64 %x, %b 210 ret i64 %c 211} 212 213define i64 @lshr_by_masked_complemented_64(i64 %x) { 214; RV32I-LABEL: lshr_by_masked_complemented_64: 215; RV32I: # %bb.0: 216; RV32I-NEXT: li a2, 63 217; RV32I-NEXT: sub a2, a2, a0 218; RV32I-NEXT: andi a4, a2, 63 219; RV32I-NEXT: addi a2, a4, -32 220; RV32I-NEXT: not a3, a0 221; RV32I-NEXT: bltz a2, .LBB8_2 222; RV32I-NEXT: # %bb.1: 223; RV32I-NEXT: srl a0, a1, a4 224; RV32I-NEXT: j .LBB8_3 225; RV32I-NEXT: .LBB8_2: 226; RV32I-NEXT: srl a0, a0, a3 227; RV32I-NEXT: not a4, a4 228; RV32I-NEXT: slli a5, a1, 1 229; RV32I-NEXT: sll a4, a5, a4 230; RV32I-NEXT: or a0, a0, a4 231; RV32I-NEXT: .LBB8_3: 232; RV32I-NEXT: srl a1, a1, a3 233; RV32I-NEXT: srai a2, a2, 31 234; RV32I-NEXT: and a1, a2, a1 235; RV32I-NEXT: ret 236; 237; RV64I-LABEL: lshr_by_masked_complemented_64: 238; RV64I: # %bb.0: 239; RV64I-NEXT: not a1, a0 240; RV64I-NEXT: srl a0, a0, a1 241; RV64I-NEXT: ret 242 %a = sub i64 63, %x 243 %b = and i64 %a, 63 244 %c = lshr i64 %x, %b 245 ret i64 %c 246} 247 248define i64 @ashr_by_masked_complemented_64(i64 %x) { 249; RV32I-LABEL: ashr_by_masked_complemented_64: 250; RV32I: # %bb.0: 251; RV32I-NEXT: li a2, 63 252; RV32I-NEXT: sub a2, a2, a0 253; RV32I-NEXT: andi a2, a2, 63 254; RV32I-NEXT: addi a3, a2, -32 255; RV32I-NEXT: bltz a3, .LBB9_2 256; RV32I-NEXT: # %bb.1: 257; RV32I-NEXT: mv a0, a1 258; RV32I-NEXT: srai a1, a1, 31 259; RV32I-NEXT: sra a0, a0, a2 260; RV32I-NEXT: ret 261; RV32I-NEXT: .LBB9_2: 262; RV32I-NEXT: not a3, a0 263; RV32I-NEXT: not a2, a2 264; RV32I-NEXT: slli a4, a1, 1 265; RV32I-NEXT: sra a1, a1, a3 266; RV32I-NEXT: srl a0, a0, a3 267; RV32I-NEXT: sll a2, a4, a2 268; RV32I-NEXT: or a0, a0, a2 269; RV32I-NEXT: ret 270; 271; RV64I-LABEL: ashr_by_masked_complemented_64: 272; RV64I: # %bb.0: 273; RV64I-NEXT: not a1, a0 274; RV64I-NEXT: sra a0, a0, a1 275; RV64I-NEXT: ret 276 %a = sub i64 63, %x 277 %b = and i64 %a, 63 278 %c = ashr i64 %x, %b 279 ret i64 %c 280} 281