Skip to content

Commit 2112e41

Browse files
committed
[InstCombine] Convert fshl(x, 0, y) to shl(x, y) or shl(X, and(Y, BitWidth - 1))
1 parent c2c901c commit 2112e41

File tree

2 files changed

+27
-8
lines changed

2 files changed

+27
-8
lines changed

llvm/lib/Transforms/InstCombine/InstCombineCalls.cpp

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2229,6 +2229,19 @@ Instruction *InstCombinerImpl::visitCallInst(CallInst &CI) {
22292229
return BitOp;
22302230
}
22312231

2232+
// fshal(X, 0, Y) --> shl(X, and(Y, BitWidth - 1))
2233+
// fshal(X, 0, Y) --> Shl(X, Y) if Y within the range 0 to type bit width
2234+
if (match(Op1, m_ZeroInt())) {
2235+
unsigned BitWidth = Ty->getScalarSizeInBits();
2236+
Value *Op2 = II->getArgOperand(2);
2237+
if (auto Range = II->getRange(); Range && Range->getLower().sge(0) &&
2238+
Range->getUpper().sle(BitWidth)) {
2239+
return BinaryOperator::CreateShl(Op0, Op2);
2240+
}
2241+
Value *And = Builder.CreateAnd(Op2, ConstantInt::get(Ty, BitWidth - 1));
2242+
return BinaryOperator::CreateShl(Op0, And);
2243+
}
2244+
22322245
// Left or right might be masked.
22332246
if (SimplifyDemandedInstructionBits(*II))
22342247
return &CI;

llvm/test/Transforms/InstCombine/fsh.ll

Lines changed: 14 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1015,7 +1015,8 @@ define <2 x i32> @fshr_vec_zero_elem(<2 x i32> %x, <2 x i32> %y) {
10151015
define i16 @fshl_i16_shl(i16 %x, i16 %y) {
10161016
; CHECK-LABEL: @fshl_i16_shl(
10171017
; CHECK-NEXT: entry:
1018-
; CHECK-NEXT: [[RES:%.*]] = call i16 @llvm.fshl.i16(i16 [[X:%.*]], i16 0, i16 [[Y:%.*]])
1018+
; CHECK-NEXT: [[TMP0:%.*]] = and i16 [[Y:%.*]], 15
1019+
; CHECK-NEXT: [[RES:%.*]] = shl i16 [[X:%.*]], [[TMP0]]
10191020
; CHECK-NEXT: ret i16 [[RES]]
10201021
;
10211022
entry:
@@ -1026,7 +1027,8 @@ entry:
10261027
define i32 @fshl_i32_shl(i32 %x, i32 %y) {
10271028
; CHECK-LABEL: @fshl_i32_shl(
10281029
; CHECK-NEXT: entry:
1029-
; CHECK-NEXT: [[RES:%.*]] = call i32 @llvm.fshl.i32(i32 [[X:%.*]], i32 0, i32 [[Y:%.*]])
1030+
; CHECK-NEXT: [[TMP0:%.*]] = and i32 [[Y:%.*]], 31
1031+
; CHECK-NEXT: [[RES:%.*]] = shl i32 [[X:%.*]], [[TMP0]]
10301032
; CHECK-NEXT: ret i32 [[RES]]
10311033
;
10321034
entry:
@@ -1037,7 +1039,8 @@ entry:
10371039
define <2 x i16> @fshl_vi16_shl(<2 x i16> %x, <2 x i16> %y) {
10381040
; CHECK-LABEL: @fshl_vi16_shl(
10391041
; CHECK-NEXT: entry:
1040-
; CHECK-NEXT: [[RES:%.*]] = call <2 x i16> @llvm.fshl.v2i16(<2 x i16> [[X:%.*]], <2 x i16> zeroinitializer, <2 x i16> [[Y:%.*]])
1042+
; CHECK-NEXT: [[TMP0:%.*]] = and <2 x i16> [[Y:%.*]], splat (i16 15)
1043+
; CHECK-NEXT: [[RES:%.*]] = shl <2 x i16> [[X:%.*]], [[TMP0]]
10411044
; CHECK-NEXT: ret <2 x i16> [[RES]]
10421045
;
10431046
entry:
@@ -1048,7 +1051,8 @@ entry:
10481051
define <2 x i31> @fshl_vi31_shl(<2 x i31> %x, <2 x i31> %y) {
10491052
; CHECK-LABEL: @fshl_vi31_shl(
10501053
; CHECK-NEXT: entry:
1051-
; CHECK-NEXT: [[RES:%.*]] = call <2 x i31> @llvm.fshl.v2i31(<2 x i31> [[X:%.*]], <2 x i31> zeroinitializer, <2 x i31> [[Y:%.*]])
1054+
; CHECK-NEXT: [[TMP0:%.*]] = and <2 x i31> [[Y:%.*]], splat (i31 30)
1055+
; CHECK-NEXT: [[RES:%.*]] = shl <2 x i31> [[X:%.*]], [[TMP0]]
10521056
; CHECK-NEXT: ret <2 x i31> [[RES]]
10531057
;
10541058
entry:
@@ -1059,7 +1063,7 @@ entry:
10591063
define i16 @fshl_i16_shl_with_range(i16 %x, i16 range(i16 0, 16) %y) {
10601064
; CHECK-LABEL: @fshl_i16_shl_with_range(
10611065
; CHECK-NEXT: entry:
1062-
; CHECK-NEXT: [[RES:%.*]] = call i16 @llvm.fshl.i16(i16 [[X:%.*]], i16 0, i16 [[Y:%.*]])
1066+
; CHECK-NEXT: [[RES:%.*]] = shl i16 [[X:%.*]], [[Y:%.*]]
10631067
; CHECK-NEXT: ret i16 [[RES]]
10641068
;
10651069
entry:
@@ -1070,7 +1074,7 @@ entry:
10701074
define i32 @fshl_i32_shl_with_range(i32 %x, i32 range(i32 0, 32) %y) {
10711075
; CHECK-LABEL: @fshl_i32_shl_with_range(
10721076
; CHECK-NEXT: entry:
1073-
; CHECK-NEXT: [[RES:%.*]] = call i32 @llvm.fshl.i32(i32 [[X:%.*]], i32 0, i32 [[Y:%.*]])
1077+
; CHECK-NEXT: [[RES:%.*]] = shl i32 [[X:%.*]], [[Y:%.*]]
10741078
; CHECK-NEXT: ret i32 [[RES]]
10751079
;
10761080
entry:
@@ -1081,7 +1085,8 @@ entry:
10811085
define i16 @fshl_i16_shl_with_range_ignored(i16 %x, i16 range(i16 0, 17) %y) {
10821086
; CHECK-LABEL: @fshl_i16_shl_with_range_ignored(
10831087
; CHECK-NEXT: entry:
1084-
; CHECK-NEXT: [[RES:%.*]] = call i16 @llvm.fshl.i16(i16 [[X:%.*]], i16 0, i16 [[Y:%.*]])
1088+
; CHECK-NEXT: [[TMP0:%.*]] = and i16 [[Y:%.*]], 15
1089+
; CHECK-NEXT: [[RES:%.*]] = shl i16 [[X:%.*]], [[TMP0]]
10851090
; CHECK-NEXT: ret i16 [[RES]]
10861091
;
10871092
entry:
@@ -1092,7 +1097,8 @@ entry:
10921097
define i32 @fshl_i32_shl_with_range_ignored(i32 %x, i32 range(i32 0, 33) %y) {
10931098
; CHECK-LABEL: @fshl_i32_shl_with_range_ignored(
10941099
; CHECK-NEXT: entry:
1095-
; CHECK-NEXT: [[RES:%.*]] = call i32 @llvm.fshl.i32(i32 [[X:%.*]], i32 0, i32 [[Y:%.*]])
1100+
; CHECK-NEXT: [[TMP0:%.*]] = and i32 [[Y:%.*]], 31
1101+
; CHECK-NEXT: [[RES:%.*]] = shl i32 [[X:%.*]], [[TMP0]]
10961102
; CHECK-NEXT: ret i32 [[RES]]
10971103
;
10981104
entry:

0 commit comments

Comments
 (0)