xref: /llvm-project/llvm/test/CodeGen/AVR/shift-expand.ll (revision 4e831753b9cf8745e9bf251f775f2399c9ef4138)
1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
2; RUN: opt -avr-shift-expand -S %s -o - | FileCheck %s
3
4; The avr-shift-expand pass expands large shifts with a non-constant shift
5; amount to a loop. These loops avoid generating a (non-existing) builtin such
6; as __ashlsi3.
7
8target datalayout = "e-P1-p:16:8-i8:8-i16:8-i32:8-i64:8-f32:8-f64:8-n8-a:8"
9target triple = "avr"
10
11define i16 @shl16(i16 %value, i16 %amount) addrspace(1) {
12; CHECK-LABEL: @shl16(
13; CHECK-NEXT:    [[RESULT:%.*]] = shl i16 [[VALUE:%.*]], [[AMOUNT:%.*]]
14; CHECK-NEXT:    ret i16 [[RESULT]]
15;
16  %result = shl i16 %value, %amount
17  ret i16 %result
18}
19
20define i32 @shl32(i32 %value, i32 %amount) addrspace(1) {
21; CHECK-LABEL: @shl32(
22; CHECK-NEXT:    [[TMP1:%.*]] = trunc i32 [[AMOUNT:%.*]] to i8
23; CHECK-NEXT:    [[TMP2:%.*]] = icmp eq i8 [[TMP1]], 0
24; CHECK-NEXT:    br i1 [[TMP2]], label [[SHIFT_DONE:%.*]], label [[SHIFT_LOOP:%.*]]
25; CHECK:       shift.loop:
26; CHECK-NEXT:    [[TMP3:%.*]] = phi i8 [ [[TMP1]], [[TMP0:%.*]] ], [ [[TMP5:%.*]], [[SHIFT_LOOP]] ]
27; CHECK-NEXT:    [[TMP4:%.*]] = phi i32 [ [[VALUE:%.*]], [[TMP0]] ], [ [[TMP6:%.*]], [[SHIFT_LOOP]] ]
28; CHECK-NEXT:    [[TMP5]] = sub i8 [[TMP3]], 1
29; CHECK-NEXT:    [[TMP6]] = shl i32 [[TMP4]], 1
30; CHECK-NEXT:    [[TMP7:%.*]] = icmp eq i8 [[TMP5]], 0
31; CHECK-NEXT:    br i1 [[TMP7]], label [[SHIFT_DONE]], label [[SHIFT_LOOP]]
32; CHECK:       shift.done:
33; CHECK-NEXT:    [[TMP8:%.*]] = phi i32 [ [[VALUE]], [[TMP0]] ], [ [[TMP6]], [[SHIFT_LOOP]] ]
34; CHECK-NEXT:    ret i32 [[TMP8]]
35;
36  %result = shl i32 %value, %amount
37  ret i32 %result
38}
39
40define i40 @shl40(i40 %value, i40 %amount) addrspace(1) {
41; CHECK-LABEL: @shl40(
42; CHECK-NEXT:    [[TMP1:%.*]] = trunc i40 [[AMOUNT:%.*]] to i8
43; CHECK-NEXT:    [[TMP2:%.*]] = icmp eq i8 [[TMP1]], 0
44; CHECK-NEXT:    br i1 [[TMP2]], label [[SHIFT_DONE:%.*]], label [[SHIFT_LOOP:%.*]]
45; CHECK:       shift.loop:
46; CHECK-NEXT:    [[TMP3:%.*]] = phi i8 [ [[TMP1]], [[TMP0:%.*]] ], [ [[TMP5:%.*]], [[SHIFT_LOOP]] ]
47; CHECK-NEXT:    [[TMP4:%.*]] = phi i40 [ [[VALUE:%.*]], [[TMP0]] ], [ [[TMP6:%.*]], [[SHIFT_LOOP]] ]
48; CHECK-NEXT:    [[TMP5]] = sub i8 [[TMP3]], 1
49; CHECK-NEXT:    [[TMP6]] = shl i40 [[TMP4]], 1
50; CHECK-NEXT:    [[TMP7:%.*]] = icmp eq i8 [[TMP5]], 0
51; CHECK-NEXT:    br i1 [[TMP7]], label [[SHIFT_DONE]], label [[SHIFT_LOOP]]
52; CHECK:       shift.done:
53; CHECK-NEXT:    [[TMP8:%.*]] = phi i40 [ [[VALUE]], [[TMP0]] ], [ [[TMP6]], [[SHIFT_LOOP]] ]
54; CHECK-NEXT:    ret i40 [[TMP8]]
55;
56  %result = shl i40 %value, %amount
57  ret i40 %result
58}
59
60; ------------------------------------------------------------------------------
61
62define i16 @lshr16(i16 %value, i16 %amount) addrspace(1) {
63; CHECK-LABEL: @lshr16(
64; CHECK-NEXT:    [[RESULT:%.*]] = lshr i16 [[VALUE:%.*]], [[AMOUNT:%.*]]
65; CHECK-NEXT:    ret i16 [[RESULT]]
66;
67  %result = lshr i16 %value, %amount
68  ret i16 %result
69}
70
71define i32 @lshr32(i32 %value, i32 %amount) addrspace(1) {
72; CHECK-LABEL: @lshr32(
73; CHECK-NEXT:    [[TMP1:%.*]] = trunc i32 [[AMOUNT:%.*]] to i8
74; CHECK-NEXT:    [[TMP2:%.*]] = icmp eq i8 [[TMP1]], 0
75; CHECK-NEXT:    br i1 [[TMP2]], label [[SHIFT_DONE:%.*]], label [[SHIFT_LOOP:%.*]]
76; CHECK:       shift.loop:
77; CHECK-NEXT:    [[TMP3:%.*]] = phi i8 [ [[TMP1]], [[TMP0:%.*]] ], [ [[TMP5:%.*]], [[SHIFT_LOOP]] ]
78; CHECK-NEXT:    [[TMP4:%.*]] = phi i32 [ [[VALUE:%.*]], [[TMP0]] ], [ [[TMP6:%.*]], [[SHIFT_LOOP]] ]
79; CHECK-NEXT:    [[TMP5]] = sub i8 [[TMP3]], 1
80; CHECK-NEXT:    [[TMP6]] = lshr i32 [[TMP4]], 1
81; CHECK-NEXT:    [[TMP7:%.*]] = icmp eq i8 [[TMP5]], 0
82; CHECK-NEXT:    br i1 [[TMP7]], label [[SHIFT_DONE]], label [[SHIFT_LOOP]]
83; CHECK:       shift.done:
84; CHECK-NEXT:    [[TMP8:%.*]] = phi i32 [ [[VALUE]], [[TMP0]] ], [ [[TMP6]], [[SHIFT_LOOP]] ]
85; CHECK-NEXT:    ret i32 [[TMP8]]
86;
87  %result = lshr i32 %value, %amount
88  ret i32 %result
89}
90
91define i40 @lshr40(i40 %value, i40 %amount) addrspace(1) {
92; CHECK-LABEL: @lshr40(
93; CHECK-NEXT:    [[TMP1:%.*]] = trunc i40 [[AMOUNT:%.*]] to i8
94; CHECK-NEXT:    [[TMP2:%.*]] = icmp eq i8 [[TMP1]], 0
95; CHECK-NEXT:    br i1 [[TMP2]], label [[SHIFT_DONE:%.*]], label [[SHIFT_LOOP:%.*]]
96; CHECK:       shift.loop:
97; CHECK-NEXT:    [[TMP3:%.*]] = phi i8 [ [[TMP1]], [[TMP0:%.*]] ], [ [[TMP5:%.*]], [[SHIFT_LOOP]] ]
98; CHECK-NEXT:    [[TMP4:%.*]] = phi i40 [ [[VALUE:%.*]], [[TMP0]] ], [ [[TMP6:%.*]], [[SHIFT_LOOP]] ]
99; CHECK-NEXT:    [[TMP5]] = sub i8 [[TMP3]], 1
100; CHECK-NEXT:    [[TMP6]] = lshr i40 [[TMP4]], 1
101; CHECK-NEXT:    [[TMP7:%.*]] = icmp eq i8 [[TMP5]], 0
102; CHECK-NEXT:    br i1 [[TMP7]], label [[SHIFT_DONE]], label [[SHIFT_LOOP]]
103; CHECK:       shift.done:
104; CHECK-NEXT:    [[TMP8:%.*]] = phi i40 [ [[VALUE]], [[TMP0]] ], [ [[TMP6]], [[SHIFT_LOOP]] ]
105; CHECK-NEXT:    ret i40 [[TMP8]]
106;
107  %result = lshr i40 %value, %amount
108  ret i40 %result
109}
110
111; ------------------------------------------------------------------------------
112
113define i16 @ashr16(i16 %value, i16 %amount) addrspace(1) {
114; CHECK-LABEL: @ashr16(
115; CHECK-NEXT:    [[RESULT:%.*]] = ashr i16 [[VALUE:%.*]], [[AMOUNT:%.*]]
116; CHECK-NEXT:    ret i16 [[RESULT]]
117;
118  %result = ashr i16 %value, %amount
119  ret i16 %result
120}
121
122define i32 @ashr32(i32 %value, i32 %amount) addrspace(1) {
123; CHECK-LABEL: @ashr32(
124; CHECK-NEXT:    [[TMP1:%.*]] = trunc i32 [[AMOUNT:%.*]] to i8
125; CHECK-NEXT:    [[TMP2:%.*]] = icmp eq i8 [[TMP1]], 0
126; CHECK-NEXT:    br i1 [[TMP2]], label [[SHIFT_DONE:%.*]], label [[SHIFT_LOOP:%.*]]
127; CHECK:       shift.loop:
128; CHECK-NEXT:    [[TMP3:%.*]] = phi i8 [ [[TMP1]], [[TMP0:%.*]] ], [ [[TMP5:%.*]], [[SHIFT_LOOP]] ]
129; CHECK-NEXT:    [[TMP4:%.*]] = phi i32 [ [[VALUE:%.*]], [[TMP0]] ], [ [[TMP6:%.*]], [[SHIFT_LOOP]] ]
130; CHECK-NEXT:    [[TMP5]] = sub i8 [[TMP3]], 1
131; CHECK-NEXT:    [[TMP6]] = ashr i32 [[TMP4]], 1
132; CHECK-NEXT:    [[TMP7:%.*]] = icmp eq i8 [[TMP5]], 0
133; CHECK-NEXT:    br i1 [[TMP7]], label [[SHIFT_DONE]], label [[SHIFT_LOOP]]
134; CHECK:       shift.done:
135; CHECK-NEXT:    [[TMP8:%.*]] = phi i32 [ [[VALUE]], [[TMP0]] ], [ [[TMP6]], [[SHIFT_LOOP]] ]
136; CHECK-NEXT:    ret i32 [[TMP8]]
137;
138  %result = ashr i32 %value, %amount
139  ret i32 %result
140}
141
142define i40 @ashr40(i40 %value, i40 %amount) addrspace(1) {
143; CHECK-LABEL: @ashr40(
144; CHECK-NEXT:    [[TMP1:%.*]] = trunc i40 [[AMOUNT:%.*]] to i8
145; CHECK-NEXT:    [[TMP2:%.*]] = icmp eq i8 [[TMP1]], 0
146; CHECK-NEXT:    br i1 [[TMP2]], label [[SHIFT_DONE:%.*]], label [[SHIFT_LOOP:%.*]]
147; CHECK:       shift.loop:
148; CHECK-NEXT:    [[TMP3:%.*]] = phi i8 [ [[TMP1]], [[TMP0:%.*]] ], [ [[TMP5:%.*]], [[SHIFT_LOOP]] ]
149; CHECK-NEXT:    [[TMP4:%.*]] = phi i40 [ [[VALUE:%.*]], [[TMP0]] ], [ [[TMP6:%.*]], [[SHIFT_LOOP]] ]
150; CHECK-NEXT:    [[TMP5]] = sub i8 [[TMP3]], 1
151; CHECK-NEXT:    [[TMP6]] = ashr i40 [[TMP4]], 1
152; CHECK-NEXT:    [[TMP7:%.*]] = icmp eq i8 [[TMP5]], 0
153; CHECK-NEXT:    br i1 [[TMP7]], label [[SHIFT_DONE]], label [[SHIFT_LOOP]]
154; CHECK:       shift.done:
155; CHECK-NEXT:    [[TMP8:%.*]] = phi i40 [ [[VALUE]], [[TMP0]] ], [ [[TMP6]], [[SHIFT_LOOP]] ]
156; CHECK-NEXT:    ret i40 [[TMP8]]
157;
158  %result = ashr i40 %value, %amount
159  ret i40 %result
160}
161