1; RUN: llc -mtriple aarch64 -mattr=+sve -asm-verbose=0 < %s | FileCheck %s 2; RUN: opt -mtriple=aarch64 -passes='require<profile-summary>,function(codegenprepare)' -S < %s | llc -mtriple=aarch64 -mattr=+sve -asm-verbose=0 | FileCheck %s 3 4; 5; RDVL 6; 7 8; CHECK-LABEL: rdvl_i8: 9; CHECK: rdvl x0, #1 10; CHECK-NEXT: ret 11define i8 @rdvl_i8() nounwind { 12 %vscale = call i8 @llvm.vscale.i8() 13 %1 = mul nsw i8 %vscale, 16 14 ret i8 %1 15} 16 17; CHECK-LABEL: rdvl_i16: 18; CHECK: rdvl x0, #1 19; CHECK-NEXT: ret 20define i16 @rdvl_i16() nounwind { 21 %vscale = call i16 @llvm.vscale.i16() 22 %1 = mul nsw i16 %vscale, 16 23 ret i16 %1 24} 25 26; CHECK-LABEL: rdvl_i32: 27; CHECK: rdvl x0, #1 28; CHECK-NEXT: ret 29define i32 @rdvl_i32() nounwind { 30 %vscale = call i32 @llvm.vscale.i32() 31 %1 = mul nsw i32 %vscale, 16 32 ret i32 %1 33} 34 35; CHECK-LABEL: rdvl_i64: 36; CHECK: rdvl x0, #1 37; CHECK-NEXT: ret 38define i64 @rdvl_i64() nounwind { 39 %vscale = call i64 @llvm.vscale.i64() 40 %1 = mul nsw i64 %vscale, 16 41 ret i64 %1 42} 43 44; CHECK-LABEL: rdvl_const: 45; CHECK: rdvl x0, #1 46; CHECK-NEXT: ret 47define i32 @rdvl_const() nounwind { 48 %vscale.ptr = getelementptr <vscale x 1 x i8>, ptr null, i64 1 49 %vscale.int = ptrtoint ptr %vscale.ptr to i32 50 %vscale.scaled = mul nsw i32 %vscale.int, 16 51 ret i32 %vscale.scaled 52} 53 54define i32 @vscale_1() nounwind { 55; CHECK-LABEL: vscale_1: 56; CHECK: rdvl [[TMP:x[0-9]+]], #1 57; CHECK-NEXT: lsr x0, [[TMP]], #4 58; CHECK-NEXT: ret 59 %vscale = call i32 @llvm.vscale.i32() 60 ret i32 %vscale 61} 62 63define i32 @vscale_neg1() nounwind { 64; CHECK-LABEL: vscale_neg1: 65; CHECK: rdvl [[TMP:x[0-9]+]], #-1 66; CHECK-NEXT: asr x0, [[TMP]], #4 67; CHECK-NEXT: ret 68 %vscale = call i32 @llvm.vscale.i32() 69 %neg = mul nsw i32 -1, %vscale 70 ret i32 %neg 71} 72 73; CHECK-LABEL: rdvl_3: 74; CHECK: rdvl [[VL_B:x[0-9]+]], #1 75; CHECK-NEXT: mov w[[MUL:[0-9]+]], #3 76; CHECK-NEXT: lsr [[VL_Q:x[0-9]+]], [[VL_B]], #4 77; CHECK-NEXT: mul x0, [[VL_Q]], x[[MUL]] 78; CHECK-NEXT: ret 79define i32 @rdvl_3() nounwind { 80 %vscale = call i32 @llvm.vscale.i32() 81 %1 = mul nsw i32 %vscale, 3 82 ret i32 %1 83} 84 85 86; CHECK-LABEL: rdvl_min: 87; CHECK: rdvl x0, #-32 88; CHECK-NEXT: ret 89define i32 @rdvl_min() nounwind { 90 %vscale = call i32 @llvm.vscale.i32() 91 %1 = mul nsw i32 %vscale, -512 92 ret i32 %1 93} 94 95; CHECK-LABEL: rdvl_max: 96; CHECK: rdvl x0, #31 97; CHECK-NEXT: ret 98define i32 @rdvl_max() nounwind { 99 %vscale = call i32 @llvm.vscale.i32() 100 %1 = mul nsw i32 %vscale, 496 101 ret i32 %1 102} 103 104define i1 @rdvl_i1() { 105; CHECK-LABEL: rdvl_i1: 106; CHECK: rdvl x8, #-1 107; CHECK-NEXT: asr x8, x8, #4 108; CHECK-NEXT: and w0, w8, #0x1 109; CHECK-NEXT: ret 110 %a = tail call i64 @llvm.vscale.i64() 111 %b = trunc i64 %a to i1 112 ret i1 %b 113} 114 115; 116; CNTH 117; 118 119; CHECK-LABEL: cnth: 120; CHECK: cnth x0{{$}} 121; CHECK-NEXT: ret 122define i32 @cnth() nounwind { 123 %vscale = call i32 @llvm.vscale.i32() 124 %1 = shl nsw i32 %vscale, 3 125 ret i32 %1 126} 127 128; CHECK-LABEL: cnth_max: 129; CHECK: cnth x0, all, mul #15 130; CHECK-NEXT: ret 131define i32 @cnth_max() nounwind { 132 %vscale = call i32 @llvm.vscale.i32() 133 %1 = mul nsw i32 %vscale, 120 134 ret i32 %1 135} 136 137; CHECK-LABEL: cnth_neg: 138; CHECK: cnth [[CNT:x[0-9]+]] 139; CHECK: neg x0, [[CNT]] 140; CHECK-NEXT: ret 141define i32 @cnth_neg() nounwind { 142 %vscale = call i32 @llvm.vscale.i32() 143 %1 = mul nsw i32 %vscale, -8 144 ret i32 %1 145} 146 147; 148; CNTW 149; 150 151; CHECK-LABEL: cntw: 152; CHECK: cntw x0{{$}} 153; CHECK-NEXT: ret 154define i32 @cntw() nounwind { 155 %vscale = call i32 @llvm.vscale.i32() 156 %1 = shl nsw i32 %vscale, 2 157 ret i32 %1 158} 159 160; CHECK-LABEL: cntw_max: 161; CHECK: cntw x0, all, mul #15 162; CHECK-NEXT: ret 163define i32 @cntw_max() nounwind { 164 %vscale = call i32 @llvm.vscale.i32() 165 %1 = mul nsw i32 %vscale, 60 166 ret i32 %1 167} 168 169; CHECK-LABEL: cntw_neg: 170; CHECK: cntw [[CNT:x[0-9]+]] 171; CHECK: neg x0, [[CNT]] 172; CHECK-NEXT: ret 173define i32 @cntw_neg() nounwind { 174 %vscale = call i32 @llvm.vscale.i32() 175 %1 = mul nsw i32 %vscale, -4 176 ret i32 %1 177} 178 179; 180; CNTD 181; 182 183; CHECK-LABEL: cntd: 184; CHECK: cntd x0{{$}} 185; CHECK-NEXT: ret 186define i32 @cntd() nounwind { 187 %vscale = call i32 @llvm.vscale.i32() 188 %1 = shl nsw i32 %vscale, 1 189 ret i32 %1 190} 191 192; CHECK-LABEL: cntd_max: 193; CHECK: cntd x0, all, mul #15 194; CHECK-NEXT: ret 195define i32 @cntd_max() nounwind { 196 %vscale = call i32 @llvm.vscale.i32() 197 %1 = mul nsw i32 %vscale, 30 198 ret i32 %1 199} 200 201; CHECK-LABEL: cntd_neg: 202; CHECK: cntd [[CNT:x[0-9]+]] 203; CHECK: neg x0, [[CNT]] 204; CHECK-NEXT: ret 205define i32 @cntd_neg() nounwind { 206 %vscale = call i32 @llvm.vscale.i32() 207 %1 = mul nsw i32 %vscale, -2 208 ret i32 %1 209} 210 211declare i8 @llvm.vscale.i8() 212declare i16 @llvm.vscale.i16() 213declare i32 @llvm.vscale.i32() 214declare i64 @llvm.vscale.i64() 215