1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147
|
; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --version 3
; RUN: opt -mtriple=arm64-darwin-unknown -S -passes=consthoist < %s | FileCheck %s
; 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
define i128 @test1(i128 %a) {
; CHECK-LABEL: define i128 @test1(
; CHECK-SAME: i128 [[A:%.*]]) {
; CHECK-NEXT: [[CONST:%.*]] = bitcast i128 12297829382473034410122878 to i128
; CHECK-NEXT: [[TMP1:%.*]] = add i128 [[A]], [[CONST]]
; CHECK-NEXT: [[TMP2:%.*]] = add i128 [[TMP1]], [[CONST]]
; CHECK-NEXT: ret i128 [[TMP2]]
;
%1 = add i128 %a, 12297829382473034410122878
%2 = add i128 %1, 12297829382473034410122878
ret i128 %2
}
; Check that we don't hoist large, but cheap constants
define i512 @test2(i512 %a) {
; CHECK-LABEL: define i512 @test2(
; CHECK-SAME: i512 [[A:%.*]]) {
; CHECK-NEXT: [[TMP1:%.*]] = and i512 [[A]], 7
; CHECK-NEXT: [[TMP2:%.*]] = or i512 [[TMP1]], 7
; CHECK-NEXT: ret i512 [[TMP2]]
;
%1 = and i512 %a, 7
%2 = or i512 %1, 7
ret i512 %2
}
; Check that we don't hoist the shift value of a shift instruction.
define i512 @test3(i512 %a) {
; CHECK-LABEL: define i512 @test3(
; CHECK-SAME: i512 [[A:%.*]]) {
; CHECK-NEXT: [[TMP1:%.*]] = shl i512 [[A]], 504
; CHECK-NEXT: [[TMP2:%.*]] = ashr i512 [[TMP1]], 504
; CHECK-NEXT: ret i512 [[TMP2]]
;
%1 = shl i512 %a, 504
%2 = ashr i512 %1, 504
ret i512 %2
}
; Ensure the code generator has the information necessary to simply sdiv.
define i64 @sdiv(i64 %a) {
; CHECK-LABEL: define i64 @sdiv(
; CHECK-SAME: i64 [[A:%.*]]) {
; CHECK-NEXT: [[TMP1:%.*]] = sdiv i64 [[A]], 4294967087
; CHECK-NEXT: [[TMP2:%.*]] = add i64 [[TMP1]], 4294967087
; CHECK-NEXT: ret i64 [[TMP2]]
;
%1 = sdiv i64 %a, 4294967087
%2 = add i64 %1, 4294967087
ret i64 %2
}
; Ensure the code generator has the information necessary to simply srem.
define i64 @srem(i64 %a) {
; CHECK-LABEL: define i64 @srem(
; CHECK-SAME: i64 [[A:%.*]]) {
; CHECK-NEXT: [[TMP1:%.*]] = srem i64 [[A]], 4294967087
; CHECK-NEXT: [[TMP2:%.*]] = add i64 [[TMP1]], 4294967087
; CHECK-NEXT: ret i64 [[TMP2]]
;
%1 = srem i64 %a, 4294967087
%2 = add i64 %1, 4294967087
ret i64 %2
}
; Ensure the code generator has the information necessary to simply udiv.
define i64 @udiv(i64 %a) {
; CHECK-LABEL: define i64 @udiv(
; CHECK-SAME: i64 [[A:%.*]]) {
; CHECK-NEXT: [[TMP1:%.*]] = udiv i64 [[A]], 4294967087
; CHECK-NEXT: [[TMP2:%.*]] = add i64 [[TMP1]], 4294967087
; CHECK-NEXT: ret i64 [[TMP2]]
;
%1 = udiv i64 %a, 4294967087
%2 = add i64 %1, 4294967087
ret i64 %2
}
; Ensure the code generator has the information necessary to simply urem.
define i64 @urem(i64 %a) {
; CHECK-LABEL: define i64 @urem(
; CHECK-SAME: i64 [[A:%.*]]) {
; CHECK-NEXT: [[TMP1:%.*]] = urem i64 [[A]], 4294967087
; CHECK-NEXT: [[TMP2:%.*]] = add i64 [[TMP1]], 4294967087
; CHECK-NEXT: ret i64 [[TMP2]]
;
%1 = urem i64 %a, 4294967087
%2 = add i64 %1, 4294967087
ret i64 %2
}
; Code generator will not decompose divide like operations when the divisor is
; no a constant.
define i64 @sdiv_non_const_divisor(i64 %a) {
; CHECK-LABEL: define i64 @sdiv_non_const_divisor(
; CHECK-SAME: i64 [[A:%.*]]) {
; CHECK-NEXT: [[CONST:%.*]] = bitcast i64 4294967087 to i64
; CHECK-NEXT: [[TMP1:%.*]] = sdiv i64 [[CONST]], [[A]]
; CHECK-NEXT: [[TMP2:%.*]] = add i64 [[TMP1]], [[CONST]]
; CHECK-NEXT: ret i64 [[TMP2]]
;
%1 = sdiv i64 4294967087, %a
%2 = add i64 %1, 4294967087
ret i64 %2
}
; Code generator emits divide instructions when optimising for size.
define i64 @sdiv_minsize(i64 %a) minsize {
; CHECK-LABEL: define i64 @sdiv_minsize(
; CHECK-SAME: i64 [[A:%.*]]) #[[ATTR0:[0-9]+]] {
; CHECK-NEXT: [[CONST:%.*]] = bitcast i64 4294967087 to i64
; CHECK-NEXT: [[TMP1:%.*]] = sdiv i64 [[A]], [[CONST]]
; CHECK-NEXT: [[TMP2:%.*]] = add i64 [[TMP1]], [[CONST]]
; CHECK-NEXT: ret i64 [[TMP2]]
;
%1 = sdiv i64 %a, 4294967087
%2 = add i64 %1, 4294967087
ret i64 %2
}
define <2 x i64> @sdiv_v2i64(<2 x i64> %a) {
; CHECK-LABEL: define <2 x i64> @sdiv_v2i64(
; CHECK-SAME: <2 x i64> [[A:%.*]]) {
; CHECK-NEXT: [[TMP1:%.*]] = sdiv <2 x i64> [[A]], splat (i64 4294967087)
; CHECK-NEXT: [[TMP2:%.*]] = add <2 x i64> [[TMP1]], splat (i64 4294967087)
; CHECK-NEXT: ret <2 x i64> [[TMP2]]
;
%1 = sdiv <2 x i64> %a, <i64 4294967087, i64 4294967087>
%2 = add <2 x i64> %1, <i64 4294967087, i64 4294967087>
ret <2 x i64> %2
}
define <vscale x 2 x i64> @sdiv_nxv2i64(<vscale x 2 x i64> %a) {
; CHECK-LABEL: define <vscale x 2 x i64> @sdiv_nxv2i64(
; CHECK-SAME: <vscale x 2 x i64> [[A:%.*]]) {
; CHECK-NEXT: [[TMP1:%.*]] = sdiv <vscale x 2 x i64> [[A]], splat (i64 4294967087)
; CHECK-NEXT: [[TMP2:%.*]] = add <vscale x 2 x i64> [[TMP1]], splat (i64 4294967087)
; CHECK-NEXT: ret <vscale x 2 x i64> [[TMP2]]
;
%1 = sdiv <vscale x 2 x i64> %a, splat (i64 4294967087)
%2 = add <vscale x 2 x i64> %1, splat (i64 4294967087)
ret <vscale x 2 x i64> %2
}
|