[ConstraintElim] Add support for decomposing gep nuw (#118639)
[llvm-project.git] / llvm / test / Transforms / AggressiveInstCombine / trunc_udivrem.ll
blob916c41f15cde98ceaa0c9a371b44d7659826a85c
1 ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
2 ; RUN: opt < %s -passes=aggressive-instcombine -S | FileCheck %s
4 define i16 @udiv_one_arg(i8 %x) {
5 ; CHECK-LABEL: @udiv_one_arg(
6 ; CHECK-NEXT:    [[ZEXT:%.*]] = zext i8 [[X:%.*]] to i16
7 ; CHECK-NEXT:    [[DIV:%.*]] = udiv i16 [[ZEXT]], 42
8 ; CHECK-NEXT:    ret i16 [[DIV]]
10   %zext = zext i8 %x to i32
11   %div = udiv i32 %zext, 42
12   %trunc = trunc i32 %div to i16
13   ret i16 %trunc
16 define i16 @udiv_two_args(i16 %x, i16 %y) {
17 ; CHECK-LABEL: @udiv_two_args(
18 ; CHECK-NEXT:    [[I0:%.*]] = udiv i16 [[X:%.*]], [[Y:%.*]]
19 ; CHECK-NEXT:    ret i16 [[I0]]
21   %zextx = zext i16 %x to i32
22   %zexty = zext i16 %y to i32
23   %i0 = udiv i32 %zextx, %zexty
24   %r = trunc i32 %i0 to i16
25   ret i16 %r
28 ; Negative test
29 define i16 @udiv_big_const(i8 %x) {
30 ; CHECK-LABEL: @udiv_big_const(
31 ; CHECK-NEXT:    [[ZEXT:%.*]] = zext i8 [[X:%.*]] to i32
32 ; CHECK-NEXT:    [[DIV:%.*]] = udiv i32 [[ZEXT]], 70000
33 ; CHECK-NEXT:    [[TRUNC:%.*]] = trunc i32 [[DIV]] to i16
34 ; CHECK-NEXT:    ret i16 [[TRUNC]]
36   %zext = zext i8 %x to i32
37   %div = udiv i32 %zext, 70000
38   %trunc = trunc i32 %div to i16
39   ret i16 %trunc
42 define <2 x i16> @udiv_vector(<2 x i8> %x) {
43 ; CHECK-LABEL: @udiv_vector(
44 ; CHECK-NEXT:    [[Z:%.*]] = zext <2 x i8> [[X:%.*]] to <2 x i16>
45 ; CHECK-NEXT:    [[S:%.*]] = udiv <2 x i16> [[Z]], <i16 4, i16 10>
46 ; CHECK-NEXT:    ret <2 x i16> [[S]]
48   %z = zext <2 x i8> %x to <2 x i32>
49   %s = udiv <2 x i32> %z, <i32 4, i32 10>
50   %t = trunc <2 x i32> %s to <2 x i16>
51   ret <2 x i16> %t
54 ; Negative test: can only fold to <2 x i16>, requiring new vector type
55 define <2 x i8> @udiv_vector_need_new_vector_type(<2 x i8> %x) {
56 ; CHECK-LABEL: @udiv_vector_need_new_vector_type(
57 ; CHECK-NEXT:    [[Z:%.*]] = zext <2 x i8> [[X:%.*]] to <2 x i32>
58 ; CHECK-NEXT:    [[S:%.*]] = udiv <2 x i32> [[Z]], <i32 4, i32 500>
59 ; CHECK-NEXT:    [[T:%.*]] = trunc <2 x i32> [[S]] to <2 x i8>
60 ; CHECK-NEXT:    ret <2 x i8> [[T]]
62   %z = zext <2 x i8> %x to <2 x i32>
63   %s = udiv <2 x i32> %z, <i32 4, i32 500>
64   %t = trunc <2 x i32> %s to <2 x i8>
65   ret <2 x i8> %t
68 ; Negative test
69 define <2 x i16> @udiv_vector_big_const(<2 x i8> %x) {
70 ; CHECK-LABEL: @udiv_vector_big_const(
71 ; CHECK-NEXT:    [[Z:%.*]] = zext <2 x i8> [[X:%.*]] to <2 x i32>
72 ; CHECK-NEXT:    [[S:%.*]] = udiv <2 x i32> [[Z]], <i32 16, i32 70000>
73 ; CHECK-NEXT:    [[T:%.*]] = trunc <2 x i32> [[S]] to <2 x i16>
74 ; CHECK-NEXT:    ret <2 x i16> [[T]]
76   %z = zext <2 x i8> %x to <2 x i32>
77   %s = udiv <2 x i32> %z, <i32 16, i32 70000>
78   %t = trunc <2 x i32> %s to <2 x i16>
79   ret <2 x i16> %t
82 define i16 @udiv_exact(i16 %x, i16 %y) {
83 ; CHECK-LABEL: @udiv_exact(
84 ; CHECK-NEXT:    [[I0:%.*]] = udiv exact i16 [[X:%.*]], [[Y:%.*]]
85 ; CHECK-NEXT:    ret i16 [[I0]]
87   %zextx = zext i16 %x to i32
88   %zexty = zext i16 %y to i32
89   %i0 = udiv exact i32 %zextx, %zexty
90   %r = trunc i32 %i0 to i16
91   ret i16 %r
95 define i16 @urem_one_arg(i8 %x) {
96 ; CHECK-LABEL: @urem_one_arg(
97 ; CHECK-NEXT:    [[ZEXT:%.*]] = zext i8 [[X:%.*]] to i16
98 ; CHECK-NEXT:    [[DIV:%.*]] = urem i16 [[ZEXT]], 42
99 ; CHECK-NEXT:    ret i16 [[DIV]]
101   %zext = zext i8 %x to i32
102   %div = urem i32 %zext, 42
103   %trunc = trunc i32 %div to i16
104   ret i16 %trunc
107 define i16 @urem_two_args(i16 %x, i16 %y) {
108 ; CHECK-LABEL: @urem_two_args(
109 ; CHECK-NEXT:    [[I0:%.*]] = urem i16 [[X:%.*]], [[Y:%.*]]
110 ; CHECK-NEXT:    ret i16 [[I0]]
112   %zextx = zext i16 %x to i32
113   %zexty = zext i16 %y to i32
114   %i0 = urem i32 %zextx, %zexty
115   %r = trunc i32 %i0 to i16
116   ret i16 %r
119 ; Negative test
120 define i16 @urem_big_const(i8 %x) {
121 ; CHECK-LABEL: @urem_big_const(
122 ; CHECK-NEXT:    [[ZEXT:%.*]] = zext i8 [[X:%.*]] to i32
123 ; CHECK-NEXT:    [[DIV:%.*]] = urem i32 [[ZEXT]], 70000
124 ; CHECK-NEXT:    [[TRUNC:%.*]] = trunc i32 [[DIV]] to i16
125 ; CHECK-NEXT:    ret i16 [[TRUNC]]
127   %zext = zext i8 %x to i32
128   %div = urem i32 %zext, 70000
129   %trunc = trunc i32 %div to i16
130   ret i16 %trunc
133 define <2 x i16> @urem_vector(<2 x i8> %x) {
134 ; CHECK-LABEL: @urem_vector(
135 ; CHECK-NEXT:    [[Z:%.*]] = zext <2 x i8> [[X:%.*]] to <2 x i16>
136 ; CHECK-NEXT:    [[S:%.*]] = urem <2 x i16> [[Z]], <i16 4, i16 10>
137 ; CHECK-NEXT:    ret <2 x i16> [[S]]
139   %z = zext <2 x i8> %x to <2 x i32>
140   %s = urem <2 x i32> %z, <i32 4, i32 10>
141   %t = trunc <2 x i32> %s to <2 x i16>
142   ret <2 x i16> %t
145 ; Negative test: can only fold to <2 x i16>, requiring new vector type
146 define <2 x i8> @urem_vector_need_new_vector_type(<2 x i8> %x) {
147 ; CHECK-LABEL: @urem_vector_need_new_vector_type(
148 ; CHECK-NEXT:    [[Z:%.*]] = zext <2 x i8> [[X:%.*]] to <2 x i32>
149 ; CHECK-NEXT:    [[S:%.*]] = urem <2 x i32> [[Z]], <i32 500, i32 10>
150 ; CHECK-NEXT:    [[T:%.*]] = trunc <2 x i32> [[S]] to <2 x i8>
151 ; CHECK-NEXT:    ret <2 x i8> [[T]]
153   %z = zext <2 x i8> %x to <2 x i32>
154   %s = urem <2 x i32> %z, <i32 500, i32 10>
155   %t = trunc <2 x i32> %s to <2 x i8>
156   ret <2 x i8> %t
159 ; Negative test
160 define <2 x i16> @urem_vector_big_const(<2 x i8> %x) {
161 ; CHECK-LABEL: @urem_vector_big_const(
162 ; CHECK-NEXT:    [[Z:%.*]] = zext <2 x i8> [[X:%.*]] to <2 x i32>
163 ; CHECK-NEXT:    [[S:%.*]] = urem <2 x i32> [[Z]], <i32 16, i32 70000>
164 ; CHECK-NEXT:    [[T:%.*]] = trunc <2 x i32> [[S]] to <2 x i16>
165 ; CHECK-NEXT:    ret <2 x i16> [[T]]
167   %z = zext <2 x i8> %x to <2 x i32>
168   %s = urem <2 x i32> %z, <i32 16, i32 70000>
169   %t = trunc <2 x i32> %s to <2 x i16>
170   ret <2 x i16> %t