1 ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
2 ; RUN: opt -avr-shift-expand -S %s -o - | FileCheck %s
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
8 target datalayout = "e-P1-p:16:8-i8:8-i16:8-i32:8-i64:8-f32:8-f64:8-n8-a:8"
11 define 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]]
16 %result = shl i16 %value, %amount
20 define 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:%.*]]
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]]
33 ; CHECK-NEXT: [[TMP8:%.*]] = phi i32 [ [[VALUE]], [[TMP0]] ], [ [[TMP6]], [[SHIFT_LOOP]] ]
34 ; CHECK-NEXT: ret i32 [[TMP8]]
36 %result = shl i32 %value, %amount
40 define 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:%.*]]
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]]
53 ; CHECK-NEXT: [[TMP8:%.*]] = phi i40 [ [[VALUE]], [[TMP0]] ], [ [[TMP6]], [[SHIFT_LOOP]] ]
54 ; CHECK-NEXT: ret i40 [[TMP8]]
56 %result = shl i40 %value, %amount
60 ; ------------------------------------------------------------------------------
62 define 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]]
67 %result = lshr i16 %value, %amount
71 define 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:%.*]]
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]]
84 ; CHECK-NEXT: [[TMP8:%.*]] = phi i32 [ [[VALUE]], [[TMP0]] ], [ [[TMP6]], [[SHIFT_LOOP]] ]
85 ; CHECK-NEXT: ret i32 [[TMP8]]
87 %result = lshr i32 %value, %amount
91 define 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:%.*]]
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]]
104 ; CHECK-NEXT: [[TMP8:%.*]] = phi i40 [ [[VALUE]], [[TMP0]] ], [ [[TMP6]], [[SHIFT_LOOP]] ]
105 ; CHECK-NEXT: ret i40 [[TMP8]]
107 %result = lshr i40 %value, %amount
111 ; ------------------------------------------------------------------------------
113 define 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]]
118 %result = ashr i16 %value, %amount
122 define 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:%.*]]
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]]
135 ; CHECK-NEXT: [[TMP8:%.*]] = phi i32 [ [[VALUE]], [[TMP0]] ], [ [[TMP6]], [[SHIFT_LOOP]] ]
136 ; CHECK-NEXT: ret i32 [[TMP8]]
138 %result = ashr i32 %value, %amount
142 define 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:%.*]]
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]]
155 ; CHECK-NEXT: [[TMP8:%.*]] = phi i40 [ [[VALUE]], [[TMP0]] ], [ [[TMP6]], [[SHIFT_LOOP]] ]
156 ; CHECK-NEXT: ret i40 [[TMP8]]
158 %result = ashr i40 %value, %amount