summaryrefslogtreecommitdiffstats
path: root/llvm/test/Transforms
diff options
context:
space:
mode:
authorSanjay Patel <spatel@rotateright.com>2019-02-26 18:26:56 +0000
committerSanjay Patel <spatel@rotateright.com>2019-02-26 18:26:56 +0000
commit9dada83d6c533376b919eaf93cea99772f180814 (patch)
treecb64eca057b5f6963635544d08533c1383fd5036 /llvm/test/Transforms
parentc0170de2222ea3e06265b6e262ced5c56784f06f (diff)
downloadbcm5719-llvm-9dada83d6c533376b919eaf93cea99772f180814.tar.gz
bcm5719-llvm-9dada83d6c533376b919eaf93cea99772f180814.zip
[InstSimplify] remove zero-shift-guard fold for general funnel shift
As discussed on llvm-dev: http://lists.llvm.org/pipermail/llvm-dev/2019-February/130491.html We can't remove the compare+select in the general case because we are treating funnel shift like a standard instruction (as opposed to a special instruction like select/phi). That means that if one of the operands of the funnel shift is poison, the result is poison regardless of whether we know that the operand is actually unused based on the instruction's particular semantics. The motivating case for this transform is the more specific rotate op (rather than funnel shift), and we are preserving the fold for that case because there is no chance of introducing extra poison when there is no anonymous extra operand to the funnel shift. llvm-svn: 354905
Diffstat (limited to 'llvm/test/Transforms')
-rw-r--r--llvm/test/Transforms/InstSimplify/call.ll42
1 files changed, 25 insertions, 17 deletions
diff --git a/llvm/test/Transforms/InstSimplify/call.ll b/llvm/test/Transforms/InstSimplify/call.ll
index dfad3efe6f3..0771e4453e3 100644
--- a/llvm/test/Transforms/InstSimplify/call.ll
+++ b/llvm/test/Transforms/InstSimplify/call.ll
@@ -470,12 +470,14 @@ define <2 x i8> @fshr_no_shift_modulo_bitwidth_splat(<2 x i8> %x, <2 x i8> %y) {
ret <2 x i8> %z
}
-; When the shift amount is 0, fshl returns its 1st parameter (x), so the guard is not needed.
+; If y is poison, eliminating the guard is not safe.
define i8 @fshl_zero_shift_guard(i8 %x, i8 %y, i8 %sh) {
; CHECK-LABEL: @fshl_zero_shift_guard(
-; CHECK-NEXT: [[F:%.*]] = call i8 @llvm.fshl.i8(i8 [[X:%.*]], i8 [[Y:%.*]], i8 [[SH:%.*]])
-; CHECK-NEXT: ret i8 [[F]]
+; CHECK-NEXT: [[C:%.*]] = icmp eq i8 [[SH:%.*]], 0
+; CHECK-NEXT: [[F:%.*]] = call i8 @llvm.fshl.i8(i8 [[X:%.*]], i8 [[Y:%.*]], i8 [[SH]])
+; CHECK-NEXT: [[S:%.*]] = select i1 [[C]], i8 [[X]], i8 [[F]]
+; CHECK-NEXT: ret i8 [[S]]
;
%c = icmp eq i8 %sh, 0
%f = call i8 @llvm.fshl.i8(i8 %x, i8 %y, i8 %sh)
@@ -483,12 +485,14 @@ define i8 @fshl_zero_shift_guard(i8 %x, i8 %y, i8 %sh) {
ret i8 %s
}
-; When the shift amount is 0, fshl returns its 1st parameter (x), so the guard is not needed.
+; If y is poison, eliminating the guard is not safe.
define i8 @fshl_zero_shift_guard_swapped(i8 %x, i8 %y, i8 %sh) {
; CHECK-LABEL: @fshl_zero_shift_guard_swapped(
-; CHECK-NEXT: [[F:%.*]] = call i8 @llvm.fshl.i8(i8 [[X:%.*]], i8 [[Y:%.*]], i8 [[SH:%.*]])
-; CHECK-NEXT: ret i8 [[F]]
+; CHECK-NEXT: [[C:%.*]] = icmp ne i8 [[SH:%.*]], 0
+; CHECK-NEXT: [[F:%.*]] = call i8 @llvm.fshl.i8(i8 [[X:%.*]], i8 [[Y:%.*]], i8 [[SH]])
+; CHECK-NEXT: [[S:%.*]] = select i1 [[C]], i8 [[F]], i8 [[X]]
+; CHECK-NEXT: ret i8 [[S]]
;
%c = icmp ne i8 %sh, 0
%f = call i8 @llvm.fshl.i8(i8 %x, i8 %y, i8 %sh)
@@ -520,12 +524,14 @@ define i8 @fshl_zero_shift_guard_inverted_swapped(i8 %x, i8 %y, i8 %sh) {
ret i8 %s
}
-; When the shift amount is 0, fshr returns its 2nd parameter (y), so the guard is not needed.
+; If x is poison, eliminating the guard is not safe.
define i9 @fshr_zero_shift_guard(i9 %x, i9 %y, i9 %sh) {
; CHECK-LABEL: @fshr_zero_shift_guard(
-; CHECK-NEXT: [[F:%.*]] = call i9 @llvm.fshr.i9(i9 [[X:%.*]], i9 [[Y:%.*]], i9 [[SH:%.*]])
-; CHECK-NEXT: ret i9 [[F]]
+; CHECK-NEXT: [[C:%.*]] = icmp eq i9 [[SH:%.*]], 0
+; CHECK-NEXT: [[F:%.*]] = call i9 @llvm.fshr.i9(i9 [[X:%.*]], i9 [[Y:%.*]], i9 [[SH]])
+; CHECK-NEXT: [[S:%.*]] = select i1 [[C]], i9 [[Y]], i9 [[F]]
+; CHECK-NEXT: ret i9 [[S]]
;
%c = icmp eq i9 %sh, 0
%f = call i9 @llvm.fshr.i9(i9 %x, i9 %y, i9 %sh)
@@ -533,12 +539,14 @@ define i9 @fshr_zero_shift_guard(i9 %x, i9 %y, i9 %sh) {
ret i9 %s
}
-; When the shift amount is 0, fshr returns its 2nd parameter (y), so the guard is not needed.
+; If x is poison, eliminating the guard is not safe.
define i9 @fshr_zero_shift_guard_swapped(i9 %x, i9 %y, i9 %sh) {
; CHECK-LABEL: @fshr_zero_shift_guard_swapped(
-; CHECK-NEXT: [[F:%.*]] = call i9 @llvm.fshr.i9(i9 [[X:%.*]], i9 [[Y:%.*]], i9 [[SH:%.*]])
-; CHECK-NEXT: ret i9 [[F]]
+; CHECK-NEXT: [[C:%.*]] = icmp ne i9 [[SH:%.*]], 0
+; CHECK-NEXT: [[F:%.*]] = call i9 @llvm.fshr.i9(i9 [[X:%.*]], i9 [[Y:%.*]], i9 [[SH]])
+; CHECK-NEXT: [[S:%.*]] = select i1 [[C]], i9 [[F]], i9 [[Y]]
+; CHECK-NEXT: ret i9 [[S]]
;
%c = icmp ne i9 %sh, 0
%f = call i9 @llvm.fshr.i9(i9 %x, i9 %y, i9 %sh)
@@ -687,14 +695,14 @@ define i8 @fshl_zero_shift_guard_wrong_select_op(i8 %x, i8 %y, i8 %sh) {
; Vector types work too.
-define <2 x i8> @fshr_zero_shift_guard_splat(<2 x i8> %x, <2 x i8> %y, <2 x i8> %sh) {
-; CHECK-LABEL: @fshr_zero_shift_guard_splat(
-; CHECK-NEXT: [[F:%.*]] = call <2 x i8> @llvm.fshr.v2i8(<2 x i8> [[X:%.*]], <2 x i8> [[Y:%.*]], <2 x i8> [[SH:%.*]])
+define <2 x i8> @rotr_zero_shift_guard_splat(<2 x i8> %x, <2 x i8> %sh) {
+; CHECK-LABEL: @rotr_zero_shift_guard_splat(
+; CHECK-NEXT: [[F:%.*]] = call <2 x i8> @llvm.fshr.v2i8(<2 x i8> [[X:%.*]], <2 x i8> [[X]], <2 x i8> [[SH:%.*]])
; CHECK-NEXT: ret <2 x i8> [[F]]
;
%c = icmp eq <2 x i8> %sh, zeroinitializer
- %f = call <2 x i8> @llvm.fshr.v2i8(<2 x i8> %x, <2 x i8> %y, <2 x i8> %sh)
- %s = select <2 x i1> %c, <2 x i8> %y, <2 x i8> %f
+ %f = call <2 x i8> @llvm.fshr.v2i8(<2 x i8> %x, <2 x i8> %x, <2 x i8> %sh)
+ %s = select <2 x i1> %c, <2 x i8> %x, <2 x i8> %f
ret <2 x i8> %s
}
OpenPOWER on IntegriCloud