The pass uses the TTI hook getIntImmCostIntrin that only supports scalar integer types. Whilst hoisting expensive vector constant is likely worthwhile, this is new behaviour and so I've followed the path taken by the GEP variant of collectConstantCandidates and simply bail for vector types.
160 lines
5.9 KiB
LLVM
160 lines
5.9 KiB
LLVM
; 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 --check-prefixes=CHECK,CV
|
|
; 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
|
|
|
|
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) {
|
|
; CV-LABEL: define <2 x i64> @sdiv_v2i64(
|
|
; CV-SAME: <2 x i64> [[A:%.*]]) {
|
|
; CV-NEXT: [[TMP1:%.*]] = sdiv <2 x i64> [[A]], <i64 4294967087, i64 4294967087>
|
|
; CV-NEXT: [[TMP2:%.*]] = add <2 x i64> [[TMP1]], <i64 4294967087, i64 4294967087>
|
|
; CV-NEXT: ret <2 x i64> [[TMP2]]
|
|
;
|
|
; CI-LABEL: define <2 x i64> @sdiv_v2i64(
|
|
; CI-SAME: <2 x i64> [[A:%.*]]) {
|
|
; CI-NEXT: [[TMP1:%.*]] = sdiv <2 x i64> [[A]], splat (i64 4294967087)
|
|
; CI-NEXT: [[TMP2:%.*]] = add <2 x i64> [[TMP1]], splat (i64 4294967087)
|
|
; CI-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) {
|
|
; CV-LABEL: define <vscale x 2 x i64> @sdiv_nxv2i64(
|
|
; CV-SAME: <vscale x 2 x i64> [[A:%.*]]) {
|
|
; 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)
|
|
; 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)
|
|
; CV-NEXT: ret <vscale x 2 x i64> [[TMP2]]
|
|
;
|
|
; CI-LABEL: define <vscale x 2 x i64> @sdiv_nxv2i64(
|
|
; CI-SAME: <vscale x 2 x i64> [[A:%.*]]) {
|
|
; CI-NEXT: [[TMP1:%.*]] = sdiv <vscale x 2 x i64> [[A]], splat (i64 4294967087)
|
|
; CI-NEXT: [[TMP2:%.*]] = add <vscale x 2 x i64> [[TMP1]], splat (i64 4294967087)
|
|
; CI-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
|
|
}
|