1; RUN: llc -mtriple=aarch64--linux-gnu -mattr=+sve --asm-verbose=false < %s 2>%t |FileCheck %s 2; RUN: FileCheck --check-prefix=WARN --allow-empty %s <%t 3 4; If this check fails please read test/CodeGen/AArch64/README for instructions on how to resolve it. 5; WARN-NOT: warning 6 7declare i32 @llvm.vscale.i32() 8declare i64 @llvm.vscale.i64() 9 10; Fold (add (vscale * C0), (vscale * C1)) to (vscale * (C0 + C1)). 11define i64 @combine_add_vscale_i64() nounwind { 12; CHECK-LABEL: combine_add_vscale_i64: 13; CHECK-NOT: add 14; CHECK-NEXT: cntd x0 15; CHECK-NEXT: ret 16 %vscale = call i64 @llvm.vscale.i64() 17 %add = add i64 %vscale, %vscale 18 ret i64 %add 19} 20 21define i32 @combine_add_vscale_i32() nounwind { 22; CHECK-LABEL: combine_add_vscale_i32: 23; CHECK-NOT: add 24; CHECK-NEXT: cntd x0 25; CHECK-NEXT: ret 26 %vscale = call i32 @llvm.vscale.i32() 27 %add = add i32 %vscale, %vscale 28 ret i32 %add 29} 30 31; Fold (mul (vscale * C0), C1) to (vscale * (C0 * C1)). 32; In this test, C0 = 1, C1 = 32. 33define i64 @combine_mul_vscale_i64() nounwind { 34; CHECK-LABEL: combine_mul_vscale_i64: 35; CHECK-NOT: mul 36; CHECK-NEXT: rdvl x0, #2 37; CHECK-NEXT: ret 38 %vscale = call i64 @llvm.vscale.i64() 39 %mul = mul i64 %vscale, 32 40 ret i64 %mul 41} 42 43define i32 @combine_mul_vscale_i32() nounwind { 44; CHECK-LABEL: combine_mul_vscale_i32: 45; CHECK-NOT: mul 46; CHECK-NEXT: rdvl x0, #3 47; CHECK-NEXT: ret 48 %vscale = call i32 @llvm.vscale.i32() 49 %mul = mul i32 %vscale, 48 50 ret i32 %mul 51} 52 53; Canonicalize (sub X, (vscale * C)) to (add X, (vscale * -C)) 54define i64 @combine_sub_vscale_i64(i64 %in) nounwind { 55; CHECK-LABEL: combine_sub_vscale_i64: 56; CHECK-NOT: sub 57; CHECK-NEXT: rdvl x8, #-1 58; CHECK-NEXT: asr x8, x8, #4 59; CHECK-NEXT: add x0, x0, x8 60; CHECK-NEXT: ret 61 %vscale = call i64 @llvm.vscale.i64() 62 %sub = sub i64 %in, %vscale 63 ret i64 %sub 64} 65 66define i32 @combine_sub_vscale_i32(i32 %in) nounwind { 67; CHECK-LABEL: combine_sub_vscale_i32: 68; CHECK-NOT: sub 69; CHECK-NEXT: rdvl x8, #-1 70; CHECK-NEXT: asr x8, x8, #4 71; CHECK-NEXT: add w0, w0, w8 72; CHECK-NEXT: ret 73 %vscale = call i32 @llvm.vscale.i32() 74 %sub = sub i32 %in, %vscale 75 ret i32 %sub 76} 77 78; Fold (shl (vscale * C0), C1) to (vscale * (C0 << C1)). 79; C0 = 1 , C1 = 4 80; At IR level, %shl = 2^4 * VSCALE. 81; At Assembly level, the output of RDVL is also 2^4 * VSCALE. 82; Hence, the immediate for RDVL is #1. 83define i64 @combine_shl_vscale_i64() nounwind { 84; CHECK-LABEL: combine_shl_vscale_i64: 85; CHECK-NOT: shl 86; CHECK-NEXT: rdvl x0, #1 87; CHECK-NEXT: ret 88 %vscale = call i64 @llvm.vscale.i64() 89 %shl = shl i64 %vscale, 4 90 ret i64 %shl 91} 92 93define i32 @combine_shl_vscale_i32() nounwind { 94; CHECK-LABEL: combine_shl_vscale_i32: 95; CHECK-NOT: shl 96; CHECK-NEXT: rdvl x0, #1 97; CHECK-NEXT: ret 98 %vscale = call i32 @llvm.vscale.i32() 99 %shl = shl i32 %vscale, 4 100 ret i32 %shl 101} 102