1; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py 2; RUN: llc -mtriple riscv64 -mattr=+m,+v < %s \ 3; RUN: | FileCheck %s -check-prefixes=RV64,RV64-VLENUNK 4; RUN: llc -mtriple riscv32 -mattr=+m,+v < %s \ 5; RUN: | FileCheck %s -check-prefix=RV32 6; RUN: llc -mtriple riscv64 -mattr=+m,+v,+zvl256b < %s \ 7; RUN: | FileCheck %s -check-prefixes=RV64,RV64-VLEN256MIN 8; RUN: llc -mtriple riscv64 -mattr=+m,+v -riscv-v-vector-bits-max=256 < %s \ 9; RUN: | FileCheck %s -check-prefixes=RV64,RV64-VLEN256MAX 10; RUN: llc -mtriple riscv64 -mattr=+m,+v,+zvl256b -riscv-v-vector-bits-max=256 < %s \ 11; RUN: | FileCheck %s -check-prefixes=RV64-VLEN256EXACT 12 13 14define i64 @vscale_zero() nounwind { 15; RV64-LABEL: vscale_zero: 16; RV64: # %bb.0: # %entry 17; RV64-NEXT: li a0, 0 18; RV64-NEXT: ret 19; 20; RV32-LABEL: vscale_zero: 21; RV32: # %bb.0: # %entry 22; RV32-NEXT: li a0, 0 23; RV32-NEXT: li a1, 0 24; RV32-NEXT: ret 25; 26; RV64-VLEN256EXACT-LABEL: vscale_zero: 27; RV64-VLEN256EXACT: # %bb.0: # %entry 28; RV64-VLEN256EXACT-NEXT: li a0, 0 29; RV64-VLEN256EXACT-NEXT: ret 30entry: 31 %0 = call i64 @llvm.vscale.i64() 32 %1 = mul i64 %0, 0 33 ret i64 %1 34} 35 36define i64 @vscale_one() nounwind { 37; RV64-LABEL: vscale_one: 38; RV64: # %bb.0: # %entry 39; RV64-NEXT: csrr a0, vlenb 40; RV64-NEXT: srli a0, a0, 3 41; RV64-NEXT: ret 42; 43; RV32-LABEL: vscale_one: 44; RV32: # %bb.0: # %entry 45; RV32-NEXT: csrr a0, vlenb 46; RV32-NEXT: srli a0, a0, 3 47; RV32-NEXT: li a1, 0 48; RV32-NEXT: ret 49; 50; RV64-VLEN256EXACT-LABEL: vscale_one: 51; RV64-VLEN256EXACT: # %bb.0: # %entry 52; RV64-VLEN256EXACT-NEXT: li a0, 4 53; RV64-VLEN256EXACT-NEXT: ret 54entry: 55 %0 = call i64 @llvm.vscale.i64() 56 %1 = mul i64 %0, 1 57 ret i64 %1 58} 59 60define i64 @vscale_uimmpow2xlen() nounwind { 61; RV64-LABEL: vscale_uimmpow2xlen: 62; RV64: # %bb.0: # %entry 63; RV64-NEXT: csrr a0, vlenb 64; RV64-NEXT: slli a0, a0, 3 65; RV64-NEXT: ret 66; 67; RV32-LABEL: vscale_uimmpow2xlen: 68; RV32: # %bb.0: # %entry 69; RV32-NEXT: csrr a0, vlenb 70; RV32-NEXT: slli a0, a0, 3 71; RV32-NEXT: li a1, 0 72; RV32-NEXT: ret 73; 74; RV64-VLEN256EXACT-LABEL: vscale_uimmpow2xlen: 75; RV64-VLEN256EXACT: # %bb.0: # %entry 76; RV64-VLEN256EXACT-NEXT: li a0, 256 77; RV64-VLEN256EXACT-NEXT: ret 78entry: 79 %0 = call i64 @llvm.vscale.i64() 80 %1 = mul i64 %0, 64 81 ret i64 %1 82} 83 84define i64 @vscale_non_pow2() nounwind { 85; RV64-LABEL: vscale_non_pow2: 86; RV64: # %bb.0: # %entry 87; RV64-NEXT: csrr a0, vlenb 88; RV64-NEXT: slli a1, a0, 1 89; RV64-NEXT: add a0, a1, a0 90; RV64-NEXT: ret 91; 92; RV32-LABEL: vscale_non_pow2: 93; RV32: # %bb.0: # %entry 94; RV32-NEXT: csrr a0, vlenb 95; RV32-NEXT: slli a1, a0, 1 96; RV32-NEXT: add a0, a1, a0 97; RV32-NEXT: li a1, 0 98; RV32-NEXT: ret 99; 100; RV64-VLEN256EXACT-LABEL: vscale_non_pow2: 101; RV64-VLEN256EXACT: # %bb.0: # %entry 102; RV64-VLEN256EXACT-NEXT: li a0, 96 103; RV64-VLEN256EXACT-NEXT: ret 104entry: 105 %0 = call i64 @llvm.vscale.i64() 106 %1 = mul i64 %0, 24 107 ret i64 %1 108} 109 110; vscale will always be a positive number, but we don't know that until after op 111; legalization. The and will be considered a NOP and replaced with its input, 112; but not until after the select becomes RISCVISD::SELECT_CC. Make sure we 113; simplify this and don't leave behind any code for calculating the select 114; condition. 115define i64 @vscale_select(i32 %x, i32 %y) { 116; RV64-LABEL: vscale_select: 117; RV64: # %bb.0: 118; RV64-NEXT: csrr a0, vlenb 119; RV64-NEXT: srli a0, a0, 3 120; RV64-NEXT: ret 121; 122; RV32-LABEL: vscale_select: 123; RV32: # %bb.0: 124; RV32-NEXT: csrr a0, vlenb 125; RV32-NEXT: srli a0, a0, 3 126; RV32-NEXT: li a1, 0 127; RV32-NEXT: ret 128; 129; RV64-VLEN256EXACT-LABEL: vscale_select: 130; RV64-VLEN256EXACT: # %bb.0: 131; RV64-VLEN256EXACT-NEXT: li a0, 4 132; RV64-VLEN256EXACT-NEXT: ret 133 %a = call i64 @llvm.vscale.i64() 134 %b = and i64 %a, 4294967295 135 %c = icmp eq i32 %x, %y 136 %d = select i1 %c, i64 %a, i64 %b 137 ret i64 %d 138} 139 140define i64 @vscale_high_bits_zero() nounwind { 141; RV64-LABEL: vscale_high_bits_zero: 142; RV64: # %bb.0: # %entry 143; RV64-NEXT: csrr a0, vlenb 144; RV64-NEXT: srli a0, a0, 3 145; RV64-NEXT: ret 146; 147; RV32-LABEL: vscale_high_bits_zero: 148; RV32: # %bb.0: # %entry 149; RV32-NEXT: csrr a0, vlenb 150; RV32-NEXT: srli a0, a0, 3 151; RV32-NEXT: li a1, 0 152; RV32-NEXT: ret 153; 154; RV64-VLEN256EXACT-LABEL: vscale_high_bits_zero: 155; RV64-VLEN256EXACT: # %bb.0: # %entry 156; RV64-VLEN256EXACT-NEXT: li a0, 4 157; RV64-VLEN256EXACT-NEXT: ret 158entry: 159 %0 = call i64 @llvm.vscale.i64() 160 %1 = and i64 %0, 2047 161 ret i64 %1 162} 163 164define i64 @vscale_masked() nounwind { 165; RV64-VLENUNK-LABEL: vscale_masked: 166; RV64-VLENUNK: # %bb.0: # %entry 167; RV64-VLENUNK-NEXT: csrr a0, vlenb 168; RV64-VLENUNK-NEXT: srli a0, a0, 3 169; RV64-VLENUNK-NEXT: andi a0, a0, 510 170; RV64-VLENUNK-NEXT: ret 171; 172; RV32-LABEL: vscale_masked: 173; RV32: # %bb.0: # %entry 174; RV32-NEXT: csrr a0, vlenb 175; RV32-NEXT: srli a0, a0, 3 176; RV32-NEXT: andi a0, a0, 510 177; RV32-NEXT: li a1, 0 178; RV32-NEXT: ret 179; 180; RV64-VLEN256MIN-LABEL: vscale_masked: 181; RV64-VLEN256MIN: # %bb.0: # %entry 182; RV64-VLEN256MIN-NEXT: csrr a0, vlenb 183; RV64-VLEN256MIN-NEXT: srli a0, a0, 3 184; RV64-VLEN256MIN-NEXT: andi a0, a0, 508 185; RV64-VLEN256MIN-NEXT: ret 186; 187; RV64-VLEN256MAX-LABEL: vscale_masked: 188; RV64-VLEN256MAX: # %bb.0: # %entry 189; RV64-VLEN256MAX-NEXT: csrr a0, vlenb 190; RV64-VLEN256MAX-NEXT: srli a0, a0, 3 191; RV64-VLEN256MAX-NEXT: ret 192; 193; RV64-VLEN256EXACT-LABEL: vscale_masked: 194; RV64-VLEN256EXACT: # %bb.0: # %entry 195; RV64-VLEN256EXACT-NEXT: li a0, 4 196; RV64-VLEN256EXACT-NEXT: ret 197entry: 198 %0 = call i64 @llvm.vscale.i64() 199 %1 = and i64 %0, 511 200 ret i64 %1 201} 202 203 204declare i64 @llvm.vscale.i64() 205