[PATCH] D93850: [InstCombine] Rewrite (switch (zext X)) as (switch X).

Chenguang Wang via Phabricator via llvm-commits llvm-commits at lists.llvm.org
Sun Dec 27 21:53:29 PST 2020


wecing created this revision.
Herald added a subscriber: hiraditya.
wecing requested review of this revision.
Herald added a project: LLVM.
Herald added a subscriber: llvm-commits.

InstCombine today rewrites (zext X == zext Y) as (X == Y), but the same
mechanics is missing for switch; instead, it tries to shrink the switch
condition type to as small as possible. This difference in behaviors
reduces the effectiveness of global value numbering.


Repository:
  rG LLVM Github Monorepo

https://reviews.llvm.org/D93850

Files:
  llvm/lib/Transforms/InstCombine/InstructionCombining.cpp
  llvm/test/Transforms/InstCombine/narrow-switch.ll


Index: llvm/test/Transforms/InstCombine/narrow-switch.ll
===================================================================
--- llvm/test/Transforms/InstCombine/narrow-switch.ll
+++ llvm/test/Transforms/InstCombine/narrow-switch.ll
@@ -260,3 +260,30 @@
   ret void
 }
 
+define void @switch_zext_with_range(i32 *%p) {
+; ALL-LABEL: @switch_zext_with_range(
+; ALL:         switch i32
+; ALL-NEXT:      i32 0, label
+; ALL-NEXT:      i32 1, label
+; ALL-NEXT:      i32 2, label
+; ALL-NEXT:      i32 3, label
+; ALL-NEXT:    ]
+;
+entry:
+  %x = load i32, i32* %p, align 4, !range !0
+  %zx = zext i32 %x to i64
+  switch i64 %zx, label %bb.err [
+    i64 0, label %bb.end
+    i64 1, label %bb.end
+    i64 2, label %bb.end
+    i64 3, label %bb.end
+  ]
+
+bb.end:
+  ret void
+
+bb.err:
+  unreachable
+}
+
+!0 = !{i32 0, i32 4}
Index: llvm/lib/Transforms/InstCombine/InstructionCombining.cpp
===================================================================
--- llvm/lib/Transforms/InstCombine/InstructionCombining.cpp
+++ llvm/lib/Transforms/InstCombine/InstructionCombining.cpp
@@ -2943,6 +2943,23 @@
 
   unsigned NewWidth = Known.getBitWidth() - std::max(LeadingKnownZeros, LeadingKnownOnes);
 
+  // Change 'switch (zext X)' into 'switch X' first, before trying the more
+  // aggressive trunc rewrite. This implements the same behavior as
+  // InstCombineCompares::foldICmpWithZextOrSext() for switch, and improves
+  // effectiveness of later passes, e.g. global value numbering.
+  Value *CastOp;
+  if (match(Cond, m_ZExtOrSExt(m_Value(CastOp)))) {
+    unsigned CastOpWidth = computeKnownBits(CastOp, 0, &SI).getBitWidth();
+    if (NewWidth > 0 && NewWidth <= CastOpWidth) {
+      for (auto Case : SI.cases()) {
+        APInt TruncatedCase =
+            Case.getCaseValue()->getValue().trunc(CastOpWidth);
+        Case.setValue(ConstantInt::get(SI.getContext(), TruncatedCase));
+      }
+      return replaceOperand(SI, 0, CastOp);
+    }
+  }
+
   // Shrink the condition operand if the new type is smaller than the old type.
   // But do not shrink to a non-standard type, because backend can't generate
   // good code for that yet.


-------------- next part --------------
A non-text attachment was scrubbed...
Name: D93850.313825.patch
Type: text/x-patch
Size: 2159 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20201228/1ed16be7/attachment.bin>


More information about the llvm-commits mailing list