[PATCH] D61152: [SimplifyCFG] use fshr instead of shl/lshr/or

Shawn Landden via Phabricator via llvm-commits llvm-commits at lists.llvm.org
Thu Apr 25 14:03:18 PDT 2019


shawnl created this revision.
shawnl added a reviewer: jmolloy.
Herald added a project: LLVM.
Herald added a subscriber: llvm-commits.

We already try (but fail due to lack of sub op)
to convert this to fshr in AggressiveInstCombine.cpp:92.

      

If a target cannot lower fshr/fshl then it needs to be fixed.
Performance on targets that have such an instruction should
not be penalized.


Repository:
  rL LLVM

https://reviews.llvm.org/D61152

Files:
  lib/Transforms/Utils/SimplifyCFG.cpp
  test/Transforms/SimplifyCFG/rangereduce.ll


Index: test/Transforms/SimplifyCFG/rangereduce.ll
===================================================================
--- test/Transforms/SimplifyCFG/rangereduce.ll
+++ test/Transforms/SimplifyCFG/rangereduce.ll
@@ -7,10 +7,8 @@
 define i32 @test1(i32 %a) {
 ; CHECK-LABEL: @test1(
 ; CHECK-NEXT:    [[TMP1:%.*]] = sub i32 [[A:%.*]], 97
-; CHECK-NEXT:    [[TMP2:%.*]] = lshr i32 [[TMP1]], 2
-; CHECK-NEXT:    [[TMP3:%.*]] = shl i32 [[TMP1]], 30
-; CHECK-NEXT:    [[TMP4:%.*]] = or i32 [[TMP2]], [[TMP3]]
-; CHECK-NEXT:    switch i32 [[TMP4]], label [[DEF:%.*]] [
+; CHECK-NEXT:    [[TMP2:%.*]] = call i32 @llvm.fshr.i32(i32 [[TMP1]], i32 [[TMP1]], i32 2)
+; CHECK-NEXT:    switch i32 [[TMP2]], label [[DEF:%.*]] [
 ; CHECK-NEXT:    i32 0, label [[ONE:%.*]]
 ; CHECK-NEXT:    i32 1, label [[TWO:%.*]]
 ; CHECK-NEXT:    i32 2, label [[THREE:%.*]]
@@ -193,10 +191,8 @@
 define i32 @test6(i32 %a) optsize {
 ; CHECK-LABEL: @test6(
 ; CHECK-NEXT:    [[TMP1:%.*]] = sub i32 [[A:%.*]], -109
-; CHECK-NEXT:    [[TMP2:%.*]] = lshr i32 [[TMP1]], 2
-; CHECK-NEXT:    [[TMP3:%.*]] = shl i32 [[TMP1]], 30
-; CHECK-NEXT:    [[TMP4:%.*]] = or i32 [[TMP2]], [[TMP3]]
-; CHECK-NEXT:    switch i32 [[TMP4]], label [[DEF:%.*]] [
+; CHECK-NEXT:    [[TMP2:%.*]] = call i32 @llvm.fshr.i32(i32 [[TMP1]], i32 [[TMP1]], i32 2)
+; CHECK-NEXT:    switch i32 [[TMP2]], label [[DEF:%.*]] [
 ; CHECK-NEXT:    i32 3, label [[ONE:%.*]]
 ; CHECK-NEXT:    i32 2, label [[TWO:%.*]]
 ; CHECK-NEXT:    i32 1, label [[THREE:%.*]]
@@ -233,13 +229,11 @@
 define i8 @test7(i8 %a) optsize {
 ; CHECK-LABEL: @test7(
 ; CHECK-NEXT:    [[TMP1:%.*]] = sub i8 [[A:%.*]], -36
-; CHECK-NEXT:    [[TMP2:%.*]] = lshr i8 [[TMP1]], 2
-; CHECK-NEXT:    [[TMP3:%.*]] = shl i8 [[TMP1]], 6
-; CHECK-NEXT:    [[TMP4:%.*]] = or i8 [[TMP2]], [[TMP3]]
-; CHECK-NEXT:    [[TMP5:%.*]] = icmp ult i8 [[TMP4]], 4
-; CHECK-NEXT:    br i1 [[TMP5]], label [[SWITCH_LOOKUP:%.*]], label [[DEF:%.*]]
+; CHECK-NEXT:    [[TMP2:%.*]] = call i8 @llvm.fshr.i8(i8 [[TMP1]], i8 [[TMP1]], i8 2)
+; CHECK-NEXT:    [[TMP3:%.*]] = icmp ult i8 [[TMP2]], 4
+; CHECK-NEXT:    br i1 [[TMP3]], label [[SWITCH_LOOKUP:%.*]], label [[DEF:%.*]]
 ; CHECK:       switch.lookup:
-; CHECK-NEXT:    [[SWITCH_CAST:%.*]] = zext i8 [[TMP4]] to i32
+; CHECK-NEXT:    [[SWITCH_CAST:%.*]] = zext i8 [[TMP2]] to i32
 ; CHECK-NEXT:    [[SWITCH_SHIFTAMT:%.*]] = mul i32 [[SWITCH_CAST]], 8
 ; CHECK-NEXT:    [[SWITCH_DOWNSHIFT:%.*]] = lshr i32 -943228976, [[SWITCH_SHIFTAMT]]
 ; CHECK-NEXT:    [[SWITCH_MASKED:%.*]] = trunc i32 [[SWITCH_DOWNSHIFT]] to i8
@@ -268,10 +262,8 @@
 define i32 @test8(i32 %a) optsize {
 ; CHECK-LABEL: @test8(
 ; CHECK-NEXT:    [[TMP1:%.*]] = sub i32 [[A:%.*]], 97
-; CHECK-NEXT:    [[TMP2:%.*]] = lshr i32 [[TMP1]], 2
-; CHECK-NEXT:    [[TMP3:%.*]] = shl i32 [[TMP1]], 30
-; CHECK-NEXT:    [[TMP4:%.*]] = or i32 [[TMP2]], [[TMP3]]
-; CHECK-NEXT:    switch i32 [[TMP4]], label [[DEF:%.*]] [
+; CHECK-NEXT:    [[TMP2:%.*]] = call i32 @llvm.fshr.i32(i32 [[TMP1]], i32 [[TMP1]], i32 2)
+; CHECK-NEXT:    switch i32 [[TMP2]], label [[DEF:%.*]] [
 ; CHECK-NEXT:    i32 0, label [[ONE:%.*]]
 ; CHECK-NEXT:    i32 1, label [[TWO:%.*]]
 ; CHECK-NEXT:    i32 2, label [[THREE:%.*]]
@@ -308,10 +300,8 @@
 define i32 @test9(i32 %a) {
 ; CHECK-LABEL: @test9(
 ; CHECK-NEXT:    [[TMP1:%.*]] = sub i32 [[A:%.*]], 6
-; CHECK-NEXT:    [[TMP2:%.*]] = lshr i32 [[TMP1]], 1
-; CHECK-NEXT:    [[TMP3:%.*]] = shl i32 [[TMP1]], 31
-; CHECK-NEXT:    [[TMP4:%.*]] = or i32 [[TMP2]], [[TMP3]]
-; CHECK-NEXT:    switch i32 [[TMP4]], label [[DEF:%.*]] [
+; CHECK-NEXT:    [[TMP2:%.*]] = call i32 @llvm.fshr.i32(i32 [[TMP1]], i32 [[TMP1]], i32 1)
+; CHECK-NEXT:    switch i32 [[TMP2]], label [[DEF:%.*]] [
 ; CHECK-NEXT:    i32 6, label [[ONE:%.*]]
 ; CHECK-NEXT:    i32 7, label [[TWO:%.*]]
 ; CHECK-NEXT:    i32 0, label [[THREE:%.*]]
Index: lib/Transforms/Utils/SimplifyCFG.cpp
===================================================================
--- lib/Transforms/Utils/SimplifyCFG.cpp
+++ lib/Transforms/Utils/SimplifyCFG.cpp
@@ -5581,9 +5581,8 @@
   Builder.SetInsertPoint(SI);
   auto *ShiftC = ConstantInt::get(Ty, Shift);
   auto *Sub = Builder.CreateSub(SI->getCondition(), ConstantInt::get(Ty, Base));
-  auto *LShr = Builder.CreateLShr(Sub, ShiftC);
-  auto *Shl = Builder.CreateShl(Sub, Ty->getBitWidth() - Shift);
-  auto *Rot = Builder.CreateOr(LShr, Shl);
+  Function *Fshr = Intrinsic::getDeclaration(SI->getModule(), Intrinsic::fshr, Ty);
+  auto *Rot = Builder.CreateCall(Fshr, {Sub, Sub, ShiftC});
   SI->replaceUsesOfWith(SI->getCondition(), Rot);
 
   for (auto Case : SI->cases()) {


-------------- next part --------------
A non-text attachment was scrubbed...
Name: D61152.196726.patch
Type: text/x-patch
Size: 4599 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20190425/cc5fccc9/attachment.bin>


More information about the llvm-commits mailing list