[InstCombine] add tests for funnel shift demanded bits; NFC

llvm-svn: 346762
This commit is contained in:
Sanjay Patel 2018-11-13 16:47:16 +00:00
parent 3635c89070
commit bcc5a74261
1 changed files with 147 additions and 0 deletions

View File

@ -0,0 +1,147 @@
; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
; RUN: opt < %s -instcombine -S | FileCheck %s
declare i32 @llvm.fshl.i32(i32, i32, i32)
declare i33 @llvm.fshr.i33(i33, i33, i33)
declare <2 x i32> @llvm.fshr.v2i32(<2 x i32>, <2 x i32>, <2 x i32>)
declare <2 x i31> @llvm.fshl.v2i31(<2 x i31>, <2 x i31>, <2 x i31>)
; If the shift mask doesn't include any demanded bits, the funnel shift can be eliminated.
define i32 @fshl_mask_simplify1(i32 %x, i32 %y, i32 %sh) {
; CHECK-LABEL: @fshl_mask_simplify1(
; CHECK-NEXT: [[MASKEDSH:%.*]] = and i32 [[SH:%.*]], 32
; CHECK-NEXT: [[R:%.*]] = call i32 @llvm.fshl.i32(i32 [[X:%.*]], i32 [[Y:%.*]], i32 [[MASKEDSH]])
; CHECK-NEXT: ret i32 [[R]]
;
%maskedsh = and i32 %sh, 32
%r = call i32 @llvm.fshl.i32(i32 %x, i32 %y, i32 %maskedsh)
ret i32 %r
}
define <2 x i32> @fshr_mask_simplify2(<2 x i32> %x, <2 x i32> %y, <2 x i32> %sh) {
; CHECK-LABEL: @fshr_mask_simplify2(
; CHECK-NEXT: [[MASKEDSH:%.*]] = and <2 x i32> [[SH:%.*]], <i32 64, i32 64>
; CHECK-NEXT: [[R:%.*]] = call <2 x i32> @llvm.fshr.v2i32(<2 x i32> [[X:%.*]], <2 x i32> [[Y:%.*]], <2 x i32> [[MASKEDSH]])
; CHECK-NEXT: ret <2 x i32> [[R]]
;
%maskedsh = and <2 x i32> %sh, <i32 64, i32 64>
%r = call <2 x i32> @llvm.fshr.v2i32(<2 x i32> %x, <2 x i32> %y, <2 x i32> %maskedsh)
ret <2 x i32> %r
}
; Negative test.
define i32 @fshl_mask_simplify3(i32 %x, i32 %y, i32 %sh) {
; CHECK-LABEL: @fshl_mask_simplify3(
; CHECK-NEXT: [[MASKEDSH:%.*]] = and i32 [[SH:%.*]], 16
; CHECK-NEXT: [[R:%.*]] = call i32 @llvm.fshl.i32(i32 [[X:%.*]], i32 [[Y:%.*]], i32 [[MASKEDSH]])
; CHECK-NEXT: ret i32 [[R]]
;
%maskedsh = and i32 %sh, 16
%r = call i32 @llvm.fshl.i32(i32 %x, i32 %y, i32 %maskedsh)
ret i32 %r
}
; Check again with weird bitwidths; log2(33) means we demand the low 6 bits.
define i33 @fshr_mask_simplify1(i33 %x, i33 %y, i33 %sh) {
; CHECK-LABEL: @fshr_mask_simplify1(
; CHECK-NEXT: [[MASKEDSH:%.*]] = and i33 [[SH:%.*]], 64
; CHECK-NEXT: [[R:%.*]] = call i33 @llvm.fshr.i33(i33 [[X:%.*]], i33 [[Y:%.*]], i33 [[MASKEDSH]])
; CHECK-NEXT: ret i33 [[R]]
;
%maskedsh = and i33 %sh, 64
%r = call i33 @llvm.fshr.i33(i33 %x, i33 %y, i33 %maskedsh)
ret i33 %r
}
; Check again with weird bitwidths; log2(31) means we demand the low 5 bits.
define <2 x i31> @fshl_mask_simplify2(<2 x i31> %x, <2 x i31> %y, <2 x i31> %sh) {
; CHECK-LABEL: @fshl_mask_simplify2(
; CHECK-NEXT: [[MASKEDSH:%.*]] = and <2 x i31> [[SH:%.*]], <i31 32, i31 32>
; CHECK-NEXT: [[R:%.*]] = call <2 x i31> @llvm.fshl.v2i31(<2 x i31> [[X:%.*]], <2 x i31> [[Y:%.*]], <2 x i31> [[MASKEDSH]])
; CHECK-NEXT: ret <2 x i31> [[R]]
;
%maskedsh = and <2 x i31> %sh, <i31 32, i31 32>
%r = call <2 x i31> @llvm.fshl.v2i31(<2 x i31> %x, <2 x i31> %y, <2 x i31> %maskedsh)
ret <2 x i31> %r
}
; Negative test.
define i33 @fshr_mask_simplify3(i33 %x, i33 %y, i33 %sh) {
; CHECK-LABEL: @fshr_mask_simplify3(
; CHECK-NEXT: [[MASKEDSH:%.*]] = and i33 [[SH:%.*]], 32
; CHECK-NEXT: [[R:%.*]] = call i33 @llvm.fshr.i33(i33 [[X:%.*]], i33 [[Y:%.*]], i33 [[MASKEDSH]])
; CHECK-NEXT: ret i33 [[R]]
;
%maskedsh = and i33 %sh, 32
%r = call i33 @llvm.fshr.i33(i33 %x, i33 %y, i33 %maskedsh)
ret i33 %r
}
; This mask op is unnecessary.
define i32 @fshl_mask_not_required(i32 %x, i32 %y, i32 %sh) {
; CHECK-LABEL: @fshl_mask_not_required(
; CHECK-NEXT: [[MASKEDSH:%.*]] = and i32 [[SH:%.*]], 31
; CHECK-NEXT: [[R:%.*]] = call i32 @llvm.fshl.i32(i32 [[X:%.*]], i32 [[Y:%.*]], i32 [[MASKEDSH]])
; CHECK-NEXT: ret i32 [[R]]
;
%maskedsh = and i32 %sh, 31
%r = call i32 @llvm.fshl.i32(i32 %x, i32 %y, i32 %maskedsh)
ret i32 %r
}
; This mask op can be reduced.
define i32 @fshl_mask_reduce_constant(i32 %x, i32 %y, i32 %sh) {
; CHECK-LABEL: @fshl_mask_reduce_constant(
; CHECK-NEXT: [[MASKEDSH:%.*]] = and i32 [[SH:%.*]], 33
; CHECK-NEXT: [[R:%.*]] = call i32 @llvm.fshl.i32(i32 [[X:%.*]], i32 [[Y:%.*]], i32 [[MASKEDSH]])
; CHECK-NEXT: ret i32 [[R]]
;
%maskedsh = and i32 %sh, 33
%r = call i32 @llvm.fshl.i32(i32 %x, i32 %y, i32 %maskedsh)
ret i32 %r
}
; But this mask op is required.
define i32 @fshl_mask_negative(i32 %x, i32 %y, i32 %sh) {
; CHECK-LABEL: @fshl_mask_negative(
; CHECK-NEXT: [[MASKEDSH:%.*]] = and i32 [[SH:%.*]], 15
; CHECK-NEXT: [[R:%.*]] = call i32 @llvm.fshl.i32(i32 [[X:%.*]], i32 [[Y:%.*]], i32 [[MASKEDSH]])
; CHECK-NEXT: ret i32 [[R]]
;
%maskedsh = and i32 %sh, 15
%r = call i32 @llvm.fshl.i32(i32 %x, i32 %y, i32 %maskedsh)
ret i32 %r
}
; The transform is not limited to mask ops.
define <2 x i32> @fshr_set_but_not_demanded_vec(<2 x i32> %x, <2 x i32> %y, <2 x i32> %sh) {
; CHECK-LABEL: @fshr_set_but_not_demanded_vec(
; CHECK-NEXT: [[BOGUSBITS:%.*]] = or <2 x i32> [[SH:%.*]], <i32 32, i32 32>
; CHECK-NEXT: [[R:%.*]] = call <2 x i32> @llvm.fshr.v2i32(<2 x i32> [[X:%.*]], <2 x i32> [[Y:%.*]], <2 x i32> [[BOGUSBITS]])
; CHECK-NEXT: ret <2 x i32> [[R]]
;
%bogusbits = or <2 x i32> %sh, <i32 32, i32 32>
%r = call <2 x i32> @llvm.fshr.v2i32(<2 x i32> %x, <2 x i32> %y, <2 x i32> %bogusbits)
ret <2 x i32> %r
}
define <2 x i31> @fshl_set_but_not_demanded_vec(<2 x i31> %x, <2 x i31> %y, <2 x i31> %sh) {
; CHECK-LABEL: @fshl_set_but_not_demanded_vec(
; CHECK-NEXT: [[BOGUSBITS:%.*]] = or <2 x i31> [[SH:%.*]], <i31 32, i31 32>
; CHECK-NEXT: [[R:%.*]] = call <2 x i31> @llvm.fshl.v2i31(<2 x i31> [[X:%.*]], <2 x i31> [[Y:%.*]], <2 x i31> [[BOGUSBITS]])
; CHECK-NEXT: ret <2 x i31> [[R]]
;
%bogusbits = or <2 x i31> %sh, <i31 32, i31 32>
%r = call <2 x i31> @llvm.fshl.v2i31(<2 x i31> %x, <2 x i31> %y, <2 x i31> %bogusbits)
ret <2 x i31> %r
}