xref: /llvm-project/llvm/test/CodeGen/AArch64/shift-by-signext.ll (revision db158c7c830807caeeb0691739c41f1d522029e9)
1; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
2; RUN: llc -mtriple=aarch64-unknown-linux-gnu < %s | FileCheck %s
3
4; If we have a shift by sign-extended value, we can replace sign-extension
5; with zero-extension.
6
7define i32 @t0_shl(i32 %x, i8 %shamt) nounwind {
8; CHECK-LABEL: t0_shl:
9; CHECK:       // %bb.0:
10; CHECK-NEXT:    sxtb w8, w1
11; CHECK-NEXT:    lsl w0, w0, w8
12; CHECK-NEXT:    ret
13  %shamt_wide = sext i8 %shamt to i32
14  %r = shl i32 %x, %shamt_wide
15  ret i32 %r
16}
17define i32 @t1_lshr(i32 %x, i8 %shamt) nounwind {
18; CHECK-LABEL: t1_lshr:
19; CHECK:       // %bb.0:
20; CHECK-NEXT:    sxtb w8, w1
21; CHECK-NEXT:    lsr w0, w0, w8
22; CHECK-NEXT:    ret
23  %shamt_wide = sext i8 %shamt to i32
24  %r = lshr i32 %x, %shamt_wide
25  ret i32 %r
26}
27define i32 @t2_ashr(i32 %x, i8 %shamt) nounwind {
28; CHECK-LABEL: t2_ashr:
29; CHECK:       // %bb.0:
30; CHECK-NEXT:    sxtb w8, w1
31; CHECK-NEXT:    asr w0, w0, w8
32; CHECK-NEXT:    ret
33  %shamt_wide = sext i8 %shamt to i32
34  %r = ashr i32 %x, %shamt_wide
35  ret i32 %r
36}
37
38define <4 x i32> @t3_vec_shl(<4 x i32> %x, <4 x i8> %shamt) nounwind {
39; CHECK-LABEL: t3_vec_shl:
40; CHECK:       // %bb.0:
41; CHECK-NEXT:    ushll v1.4s, v1.4h, #0
42; CHECK-NEXT:    shl v1.4s, v1.4s, #24
43; CHECK-NEXT:    sshr v1.4s, v1.4s, #24
44; CHECK-NEXT:    ushl v0.4s, v0.4s, v1.4s
45; CHECK-NEXT:    ret
46  %shamt_wide = sext <4 x i8> %shamt to <4 x i32>
47  %r = shl <4 x i32> %x, %shamt_wide
48  ret <4 x i32> %r
49}
50define <4 x i32> @t4_vec_lshr(<4 x i32> %x, <4 x i8> %shamt) nounwind {
51; CHECK-LABEL: t4_vec_lshr:
52; CHECK:       // %bb.0:
53; CHECK-NEXT:    ushll v1.4s, v1.4h, #0
54; CHECK-NEXT:    shl v1.4s, v1.4s, #24
55; CHECK-NEXT:    sshr v1.4s, v1.4s, #24
56; CHECK-NEXT:    neg v1.4s, v1.4s
57; CHECK-NEXT:    ushl v0.4s, v0.4s, v1.4s
58; CHECK-NEXT:    ret
59  %shamt_wide = sext <4 x i8> %shamt to <4 x i32>
60  %r = lshr <4 x i32> %x, %shamt_wide
61  ret <4 x i32> %r
62}
63define <4 x i32> @t5_vec_ashr(<4 x i32> %x, <4 x i8> %shamt) nounwind {
64; CHECK-LABEL: t5_vec_ashr:
65; CHECK:       // %bb.0:
66; CHECK-NEXT:    ushll v1.4s, v1.4h, #0
67; CHECK-NEXT:    shl v1.4s, v1.4s, #24
68; CHECK-NEXT:    sshr v1.4s, v1.4s, #24
69; CHECK-NEXT:    neg v1.4s, v1.4s
70; CHECK-NEXT:    sshl v0.4s, v0.4s, v1.4s
71; CHECK-NEXT:    ret
72  %shamt_wide = sext <4 x i8> %shamt to <4 x i32>
73  %r = ashr <4 x i32> %x, %shamt_wide
74  ret <4 x i32> %r
75}
76
77; This is not valid for funnel shifts
78declare i32 @llvm.fshl.i32(i32 %a, i32 %b, i32 %c)
79declare i32 @llvm.fshr.i32(i32 %a, i32 %b, i32 %c)
80define i32 @n6_fshl(i32 %x, i32 %y, i8 %shamt) nounwind {
81; CHECK-LABEL: n6_fshl:
82; CHECK:       // %bb.0:
83; CHECK-NEXT:    lsr w8, w1, #1
84; CHECK-NEXT:    // kill: def $w2 killed $w2 def $x2
85; CHECK-NEXT:    mvn w9, w2
86; CHECK-NEXT:    lsl w10, w0, w2
87; CHECK-NEXT:    lsr w8, w8, w9
88; CHECK-NEXT:    orr w0, w10, w8
89; CHECK-NEXT:    ret
90  %shamt_wide = sext i8 %shamt to i32
91  %r = call i32 @llvm.fshl.i32(i32 %x, i32 %y, i32 %shamt_wide)
92  ret i32 %r
93}
94define i32 @n7_fshr(i32 %x, i32 %y, i8 %shamt) nounwind {
95; CHECK-LABEL: n7_fshr:
96; CHECK:       // %bb.0:
97; CHECK-NEXT:    lsl w8, w0, #1
98; CHECK-NEXT:    // kill: def $w2 killed $w2 def $x2
99; CHECK-NEXT:    mvn w9, w2
100; CHECK-NEXT:    lsr w10, w1, w2
101; CHECK-NEXT:    lsl w8, w8, w9
102; CHECK-NEXT:    orr w0, w8, w10
103; CHECK-NEXT:    ret
104  %shamt_wide = sext i8 %shamt to i32
105  %r = call i32 @llvm.fshr.i32(i32 %x, i32 %y, i32 %shamt_wide)
106  ret i32 %r
107}
108
109define i32 @n8_extrause(i32 %x, i8 %shamt, ptr %shamt_wide_store) nounwind {
110; CHECK-LABEL: n8_extrause:
111; CHECK:       // %bb.0:
112; CHECK-NEXT:    sxtb w8, w1
113; CHECK-NEXT:    lsl w0, w0, w8
114; CHECK-NEXT:    str w8, [x2]
115; CHECK-NEXT:    ret
116  %shamt_wide = sext i8 %shamt to i32
117  store i32 %shamt_wide, ptr %shamt_wide_store, align 4
118  %r = shl i32 %x, %shamt_wide
119  ret i32 %r
120}
121