[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