forked from OSchip/llvm-project
[InstCombine] add tests for funnel shift demanded bits; NFC
llvm-svn: 346762
This commit is contained in:
parent
3635c89070
commit
bcc5a74261
|
@ -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
|
||||
}
|
||||
|
Loading…
Reference in New Issue