1 ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --version 3
2 ; RUN: opt -mtriple=arm64-darwin-unknown -S -passes=consthoist < %s | FileCheck %s --check-prefixes=CHECK,CV
3 ; RUN: opt -mtriple=arm64-darwin-unknown -S -passes=consthoist -use-constant-int-for-fixed-length-splat -use-constant-int-for-scalable-splat < %s | FileCheck %s --check-prefixes=CHECK,CI
5 define i128 @test1(i128 %a) {
6 ; CHECK-LABEL: define i128 @test1(
7 ; CHECK-SAME: i128 [[A:%.*]]) {
8 ; CHECK-NEXT: [[CONST:%.*]] = bitcast i128 12297829382473034410122878 to i128
9 ; CHECK-NEXT: [[TMP1:%.*]] = add i128 [[A]], [[CONST]]
10 ; CHECK-NEXT: [[TMP2:%.*]] = add i128 [[TMP1]], [[CONST]]
11 ; CHECK-NEXT: ret i128 [[TMP2]]
13 %1 = add i128 %a, 12297829382473034410122878
14 %2 = add i128 %1, 12297829382473034410122878
18 ; Check that we don't hoist large, but cheap constants
19 define i512 @test2(i512 %a) {
20 ; CHECK-LABEL: define i512 @test2(
21 ; CHECK-SAME: i512 [[A:%.*]]) {
22 ; CHECK-NEXT: [[TMP1:%.*]] = and i512 [[A]], 7
23 ; CHECK-NEXT: [[TMP2:%.*]] = or i512 [[TMP1]], 7
24 ; CHECK-NEXT: ret i512 [[TMP2]]
31 ; Check that we don't hoist the shift value of a shift instruction.
32 define i512 @test3(i512 %a) {
33 ; CHECK-LABEL: define i512 @test3(
34 ; CHECK-SAME: i512 [[A:%.*]]) {
35 ; CHECK-NEXT: [[TMP1:%.*]] = shl i512 [[A]], 504
36 ; CHECK-NEXT: [[TMP2:%.*]] = ashr i512 [[TMP1]], 504
37 ; CHECK-NEXT: ret i512 [[TMP2]]
40 %2 = ashr i512 %1, 504
44 ; Ensure the code generator has the information necessary to simply sdiv.
45 define i64 @sdiv(i64 %a) {
46 ; CHECK-LABEL: define i64 @sdiv(
47 ; CHECK-SAME: i64 [[A:%.*]]) {
48 ; CHECK-NEXT: [[TMP1:%.*]] = sdiv i64 [[A]], 4294967087
49 ; CHECK-NEXT: [[TMP2:%.*]] = add i64 [[TMP1]], 4294967087
50 ; CHECK-NEXT: ret i64 [[TMP2]]
52 %1 = sdiv i64 %a, 4294967087
53 %2 = add i64 %1, 4294967087
57 ; Ensure the code generator has the information necessary to simply srem.
58 define i64 @srem(i64 %a) {
59 ; CHECK-LABEL: define i64 @srem(
60 ; CHECK-SAME: i64 [[A:%.*]]) {
61 ; CHECK-NEXT: [[TMP1:%.*]] = srem i64 [[A]], 4294967087
62 ; CHECK-NEXT: [[TMP2:%.*]] = add i64 [[TMP1]], 4294967087
63 ; CHECK-NEXT: ret i64 [[TMP2]]
65 %1 = srem i64 %a, 4294967087
66 %2 = add i64 %1, 4294967087
70 ; Ensure the code generator has the information necessary to simply udiv.
71 define i64 @udiv(i64 %a) {
72 ; CHECK-LABEL: define i64 @udiv(
73 ; CHECK-SAME: i64 [[A:%.*]]) {
74 ; CHECK-NEXT: [[TMP1:%.*]] = udiv i64 [[A]], 4294967087
75 ; CHECK-NEXT: [[TMP2:%.*]] = add i64 [[TMP1]], 4294967087
76 ; CHECK-NEXT: ret i64 [[TMP2]]
78 %1 = udiv i64 %a, 4294967087
79 %2 = add i64 %1, 4294967087
83 ; Ensure the code generator has the information necessary to simply urem.
84 define i64 @urem(i64 %a) {
85 ; CHECK-LABEL: define i64 @urem(
86 ; CHECK-SAME: i64 [[A:%.*]]) {
87 ; CHECK-NEXT: [[TMP1:%.*]] = urem i64 [[A]], 4294967087
88 ; CHECK-NEXT: [[TMP2:%.*]] = add i64 [[TMP1]], 4294967087
89 ; CHECK-NEXT: ret i64 [[TMP2]]
91 %1 = urem i64 %a, 4294967087
92 %2 = add i64 %1, 4294967087
96 ; Code generator will not decompose divide like operations when the divisor is
98 define i64 @sdiv_non_const_divisor(i64 %a) {
99 ; CHECK-LABEL: define i64 @sdiv_non_const_divisor(
100 ; CHECK-SAME: i64 [[A:%.*]]) {
101 ; CHECK-NEXT: [[CONST:%.*]] = bitcast i64 4294967087 to i64
102 ; CHECK-NEXT: [[TMP1:%.*]] = sdiv i64 [[CONST]], [[A]]
103 ; CHECK-NEXT: [[TMP2:%.*]] = add i64 [[TMP1]], [[CONST]]
104 ; CHECK-NEXT: ret i64 [[TMP2]]
106 %1 = sdiv i64 4294967087, %a
107 %2 = add i64 %1, 4294967087
111 ; Code generator emits divide instructions when optimising for size.
112 define i64 @sdiv_minsize(i64 %a) minsize {
113 ; CHECK-LABEL: define i64 @sdiv_minsize(
114 ; CHECK-SAME: i64 [[A:%.*]]) #[[ATTR0:[0-9]+]] {
115 ; CHECK-NEXT: [[CONST:%.*]] = bitcast i64 4294967087 to i64
116 ; CHECK-NEXT: [[TMP1:%.*]] = sdiv i64 [[A]], [[CONST]]
117 ; CHECK-NEXT: [[TMP2:%.*]] = add i64 [[TMP1]], [[CONST]]
118 ; CHECK-NEXT: ret i64 [[TMP2]]
120 %1 = sdiv i64 %a, 4294967087
121 %2 = add i64 %1, 4294967087
125 define <2 x i64> @sdiv_v2i64(<2 x i64> %a) {
126 ; CV-LABEL: define <2 x i64> @sdiv_v2i64(
127 ; CV-SAME: <2 x i64> [[A:%.*]]) {
128 ; CV-NEXT: [[TMP1:%.*]] = sdiv <2 x i64> [[A]], <i64 4294967087, i64 4294967087>
129 ; CV-NEXT: [[TMP2:%.*]] = add <2 x i64> [[TMP1]], <i64 4294967087, i64 4294967087>
130 ; CV-NEXT: ret <2 x i64> [[TMP2]]
132 ; CI-LABEL: define <2 x i64> @sdiv_v2i64(
133 ; CI-SAME: <2 x i64> [[A:%.*]]) {
134 ; CI-NEXT: [[TMP1:%.*]] = sdiv <2 x i64> [[A]], splat (i64 4294967087)
135 ; CI-NEXT: [[TMP2:%.*]] = add <2 x i64> [[TMP1]], splat (i64 4294967087)
136 ; CI-NEXT: ret <2 x i64> [[TMP2]]
138 %1 = sdiv <2 x i64> %a, <i64 4294967087, i64 4294967087>
139 %2 = add <2 x i64> %1, <i64 4294967087, i64 4294967087>
143 define <vscale x 2 x i64> @sdiv_nxv2i64(<vscale x 2 x i64> %a) {
144 ; CV-LABEL: define <vscale x 2 x i64> @sdiv_nxv2i64(
145 ; CV-SAME: <vscale x 2 x i64> [[A:%.*]]) {
146 ; CV-NEXT: [[TMP1:%.*]] = sdiv <vscale x 2 x i64> [[A]], shufflevector (<vscale x 2 x i64> insertelement (<vscale x 2 x i64> poison, i64 4294967087, i64 0), <vscale x 2 x i64> poison, <vscale x 2 x i32> zeroinitializer)
147 ; CV-NEXT: [[TMP2:%.*]] = add <vscale x 2 x i64> [[TMP1]], shufflevector (<vscale x 2 x i64> insertelement (<vscale x 2 x i64> poison, i64 4294967087, i64 0), <vscale x 2 x i64> poison, <vscale x 2 x i32> zeroinitializer)
148 ; CV-NEXT: ret <vscale x 2 x i64> [[TMP2]]
150 ; CI-LABEL: define <vscale x 2 x i64> @sdiv_nxv2i64(
151 ; CI-SAME: <vscale x 2 x i64> [[A:%.*]]) {
152 ; CI-NEXT: [[TMP1:%.*]] = sdiv <vscale x 2 x i64> [[A]], splat (i64 4294967087)
153 ; CI-NEXT: [[TMP2:%.*]] = add <vscale x 2 x i64> [[TMP1]], splat (i64 4294967087)
154 ; CI-NEXT: ret <vscale x 2 x i64> [[TMP2]]
156 %1 = sdiv <vscale x 2 x i64> %a, splat (i64 4294967087)
157 %2 = add <vscale x 2 x i64> %1, splat (i64 4294967087)
158 ret <vscale x 2 x i64> %2