183 lines · plain
1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py2; RUN: opt < %s -passes=instcombine -S | FileCheck %s3 4declare i8 @llvm.fshl.i8(i8, i8, i8)5declare i8 @llvm.fshr.i8(i8, i8, i8)6declare <2 x i5> @llvm.fshl.v2i5(<2 x i5>, <2 x i5>, <2 x i5>)7declare void @use(i8)8 9define i1 @rotl_eq_0(i8 %x, i8 %y) {10; CHECK-LABEL: @rotl_eq_0(11; CHECK-NEXT: [[R:%.*]] = icmp eq i8 [[X:%.*]], 012; CHECK-NEXT: ret i1 [[R]]13;14 %rot = tail call i8 @llvm.fshl.i8(i8 %x, i8 %x, i8 %y)15 %r = icmp eq i8 %rot, 016 ret i1 %r17}18 19; Extra use is ok.20 21define i1 @rotl_ne_0(i8 %x, i8 %y) {22; CHECK-LABEL: @rotl_ne_0(23; CHECK-NEXT: [[ROT:%.*]] = tail call i8 @llvm.fshl.i8(i8 [[X:%.*]], i8 [[X]], i8 [[Y:%.*]])24; CHECK-NEXT: call void @use(i8 [[ROT]])25; CHECK-NEXT: [[R:%.*]] = icmp ne i8 [[X]], 026; CHECK-NEXT: ret i1 [[R]]27;28 %rot = tail call i8 @llvm.fshl.i8(i8 %x, i8 %x, i8 %y)29 call void @use(i8 %rot)30 %r = icmp ne i8 %rot, 031 ret i1 %r32}33 34define i1 @rotl_eq_n1(i8 %x, i8 %y) {35; CHECK-LABEL: @rotl_eq_n1(36; CHECK-NEXT: [[R:%.*]] = icmp eq i8 [[X:%.*]], -137; CHECK-NEXT: ret i1 [[R]]38;39 %rot = tail call i8 @llvm.fshl.i8(i8 %x, i8 %x, i8 %y)40 %r = icmp eq i8 %rot, -141 ret i1 %r42}43 44; Vectors work too.45 46define <2 x i1> @rotl_ne_n1(<2 x i5> %x, <2 x i5> %y) {47; CHECK-LABEL: @rotl_ne_n1(48; CHECK-NEXT: [[R:%.*]] = icmp ne <2 x i5> [[X:%.*]], splat (i5 -1)49; CHECK-NEXT: ret <2 x i1> [[R]]50;51 %rot = tail call <2 x i5> @llvm.fshl.v2i5(<2 x i5>%x, <2 x i5> %x, <2 x i5> %y)52 %r = icmp ne <2 x i5> %rot, <i5 -1, i5 -1>53 ret <2 x i1> %r54}55 56define <2 x i1> @rotl_ne_n1_poison(<2 x i5> %x, <2 x i5> %y) {57; CHECK-LABEL: @rotl_ne_n1_poison(58; CHECK-NEXT: [[R:%.*]] = icmp ne <2 x i5> [[X:%.*]], <i5 -1, i5 poison>59; CHECK-NEXT: ret <2 x i1> [[R]]60;61 %rot = tail call <2 x i5> @llvm.fshl.v2i5(<2 x i5>%x, <2 x i5> %x, <2 x i5> %y)62 %r = icmp ne <2 x i5> %rot, <i5 -1, i5 poison>63 ret <2 x i1> %r64}65 66define <2 x i1> @rotl_eq_0_poison(<2 x i5> %x, <2 x i5> %y) {67; CHECK-LABEL: @rotl_eq_0_poison(68; CHECK-NEXT: [[R:%.*]] = icmp eq <2 x i5> [[X:%.*]], <i5 0, i5 poison>69; CHECK-NEXT: ret <2 x i1> [[R]]70;71 %rot = tail call <2 x i5> @llvm.fshl.v2i5(<2 x i5>%x, <2 x i5> %x, <2 x i5> %y)72 %r = icmp eq <2 x i5> %rot, <i5 0, i5 poison>73 ret <2 x i1> %r74}75 76; negative test - wrong constant value77 78define <2 x i1> @rotl_eq_1_poison(<2 x i5> %x, <2 x i5> %y) {79; CHECK-LABEL: @rotl_eq_1_poison(80; CHECK-NEXT: [[ROT:%.*]] = tail call <2 x i5> @llvm.fshl.v2i5(<2 x i5> [[X:%.*]], <2 x i5> [[X]], <2 x i5> [[Y:%.*]])81; CHECK-NEXT: [[R:%.*]] = icmp eq <2 x i5> [[ROT]], <i5 poison, i5 1>82; CHECK-NEXT: ret <2 x i1> [[R]]83;84 %rot = tail call <2 x i5> @llvm.fshl.v2i5(<2 x i5>%x, <2 x i5> %x, <2 x i5> %y)85 %r = icmp eq <2 x i5> %rot, <i5 poison, i5 1>86 ret <2 x i1> %r87}88 89; negative test - wrong predicate90 91define <2 x i1> @rotl_sgt_0_poison(<2 x i5> %x, <2 x i5> %y) {92; CHECK-LABEL: @rotl_sgt_0_poison(93; CHECK-NEXT: [[ROT:%.*]] = tail call <2 x i5> @llvm.fshl.v2i5(<2 x i5> [[X:%.*]], <2 x i5> [[X]], <2 x i5> [[Y:%.*]])94; CHECK-NEXT: [[R:%.*]] = icmp sgt <2 x i5> [[ROT]], <i5 0, i5 poison>95; CHECK-NEXT: ret <2 x i1> [[R]]96;97 %rot = tail call <2 x i5> @llvm.fshl.v2i5(<2 x i5>%x, <2 x i5> %x, <2 x i5> %y)98 %r = icmp sgt <2 x i5> %rot, <i5 0, i5 poison>99 ret <2 x i1> %r100}101 102define i1 @rotr_eq_0(i8 %x, i8 %y) {103; CHECK-LABEL: @rotr_eq_0(104; CHECK-NEXT: [[ROT:%.*]] = tail call i8 @llvm.fshr.i8(i8 [[X:%.*]], i8 [[X]], i8 [[Y:%.*]])105; CHECK-NEXT: call void @use(i8 [[ROT]])106; CHECK-NEXT: [[R:%.*]] = icmp eq i8 [[X]], 0107; CHECK-NEXT: ret i1 [[R]]108;109 %rot = tail call i8 @llvm.fshr.i8(i8 %x, i8 %x, i8 %y)110 call void @use(i8 %rot)111 %r = icmp eq i8 %rot, 0112 ret i1 %r113}114 115define i1 @rotr_ne_0(i8 %x, i8 %y) {116; CHECK-LABEL: @rotr_ne_0(117; CHECK-NEXT: [[R:%.*]] = icmp ne i8 [[X:%.*]], 0118; CHECK-NEXT: ret i1 [[R]]119;120 %rot = tail call i8 @llvm.fshr.i8(i8 %x, i8 %x, i8 %y)121 %r = icmp ne i8 %rot, 0122 ret i1 %r123}124 125define i1 @rotr_eq_n1(i8 %x, i8 %y) {126; CHECK-LABEL: @rotr_eq_n1(127; CHECK-NEXT: [[R:%.*]] = icmp eq i8 [[X:%.*]], -1128; CHECK-NEXT: ret i1 [[R]]129;130 %rot = tail call i8 @llvm.fshr.i8(i8 %x, i8 %x, i8 %y)131 %r = icmp eq i8 %rot, -1132 ret i1 %r133}134 135define i1 @rotr_ne_n1(i8 %x, i8 %y) {136; CHECK-LABEL: @rotr_ne_n1(137; CHECK-NEXT: [[R:%.*]] = icmp ne i8 [[X:%.*]], -1138; CHECK-NEXT: ret i1 [[R]]139;140 %rot = tail call i8 @llvm.fshr.i8(i8 %x, i8 %x, i8 %y)141 %r = icmp ne i8 %rot, -1142 ret i1 %r143}144 145; negative test - wrong constant value146 147define i1 @rotr_ne_1(i8 %x, i8 %y) {148; CHECK-LABEL: @rotr_ne_1(149; CHECK-NEXT: [[ROT:%.*]] = tail call i8 @llvm.fshr.i8(i8 [[X:%.*]], i8 [[X]], i8 [[Y:%.*]])150; CHECK-NEXT: [[R:%.*]] = icmp ne i8 [[ROT]], 1151; CHECK-NEXT: ret i1 [[R]]152;153 %rot = tail call i8 @llvm.fshr.i8(i8 %x, i8 %x, i8 %y)154 %r = icmp ne i8 %rot, 1155 ret i1 %r156}157 158; negative test - wrong predicate159 160define i1 @rotr_sgt_n1(i8 %x, i8 %y) {161; CHECK-LABEL: @rotr_sgt_n1(162; CHECK-NEXT: [[ROT:%.*]] = tail call i8 @llvm.fshr.i8(i8 [[X:%.*]], i8 [[X]], i8 [[Y:%.*]])163; CHECK-NEXT: [[R:%.*]] = icmp sgt i8 [[ROT]], -1164; CHECK-NEXT: ret i1 [[R]]165;166 %rot = tail call i8 @llvm.fshr.i8(i8 %x, i8 %x, i8 %y)167 %r = icmp sgt i8 %rot, -1168 ret i1 %r169}170 171; negative test - must be a rotate, not general funnel shift172 173define i1 @fshr_sgt_n1(i8 %x, i8 %y, i8 %z) {174; CHECK-LABEL: @fshr_sgt_n1(175; CHECK-NEXT: [[FSH:%.*]] = tail call i8 @llvm.fshr.i8(i8 [[X:%.*]], i8 [[Y:%.*]], i8 [[Z:%.*]])176; CHECK-NEXT: [[R:%.*]] = icmp eq i8 [[FSH]], -1177; CHECK-NEXT: ret i1 [[R]]178;179 %fsh = tail call i8 @llvm.fshr.i8(i8 %x, i8 %y, i8 %z)180 %r = icmp eq i8 %fsh, -1181 ret i1 %r182}183