[llvm] [InstCombine] Fold `lshr -> zext -> shl` patterns (PR #147737)
Matt Arsenault via llvm-commits
llvm-commits at lists.llvm.org
Thu Jul 10 20:30:32 PDT 2025
================
@@ -0,0 +1,69 @@
+; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --version 5
+; RUN: opt -S -passes=instcombine %s | FileCheck %s
+
+define i64 @simple(i32 %x) {
+; CHECK-LABEL: define i64 @simple(
+; CHECK-SAME: i32 [[X:%.*]]) {
+; CHECK-NEXT: [[LSHR:%.*]] = and i32 [[X]], -256
+; CHECK-NEXT: [[TMP1:%.*]] = zext i32 [[LSHR]] to i64
+; CHECK-NEXT: [[SHL:%.*]] = shl nuw nsw i64 [[TMP1]], 24
+; CHECK-NEXT: ret i64 [[SHL]]
+;
+ %lshr = lshr i32 %x, 8
+ %zext = zext i32 %lshr to i64
+ %shl = shl i64 %zext, 32
+ ret i64 %shl
+}
+
+;; u0xff0 = 4080
+define i64 @masked(i32 %x) {
+; CHECK-LABEL: define i64 @masked(
+; CHECK-SAME: i32 [[X:%.*]]) {
+; CHECK-NEXT: [[MASK:%.*]] = and i32 [[X]], 4080
+; CHECK-NEXT: [[TMP1:%.*]] = zext nneg i32 [[MASK]] to i64
+; CHECK-NEXT: [[SHL:%.*]] = shl nuw nsw i64 [[TMP1]], 44
+; CHECK-NEXT: ret i64 [[SHL]]
+;
+ %lshr = lshr i32 %x, 4
+ %mask = and i32 %lshr, u0xff
+ %zext = zext i32 %mask to i64
+ %shl = shl i64 %zext, 48
+ ret i64 %shl
+}
+
+define i64 @combine(i32 %lower, i32 %upper) {
+; CHECK-LABEL: define i64 @combine(
+; CHECK-SAME: i32 [[LOWER:%.*]], i32 [[UPPER:%.*]]) {
+; CHECK-NEXT: [[BASE:%.*]] = zext i32 [[LOWER]] to i64
+; CHECK-NEXT: [[TMP1:%.*]] = zext i32 [[UPPER]] to i64
+; CHECK-NEXT: [[TMP2:%.*]] = shl nuw i64 [[TMP1]], 32
+; CHECK-NEXT: [[O_3:%.*]] = or disjoint i64 [[TMP2]], [[BASE]]
+; CHECK-NEXT: ret i64 [[O_3]]
+;
+ %base = zext i32 %lower to i64
+
+ %u.0 = and i32 %upper, u0xff
+ %z.0 = zext i32 %u.0 to i64
+ %s.0 = shl i64 %z.0, 32
+ %o.0 = or i64 %base, %s.0
+
+ %r.1 = lshr i32 %upper, 8
+ %u.1 = and i32 %r.1, u0xff
+ %z.1 = zext i32 %u.1 to i64
+ %s.1 = shl i64 %z.1, 40
+ %o.1 = or i64 %o.0, %s.1
+
+ %r.2 = lshr i32 %upper, 16
+ %u.2 = and i32 %r.2, u0xff
+ %z.2 = zext i32 %u.2 to i64
+ %s.2 = shl i64 %z.2, 48
+ %o.2 = or i64 %o.1, %s.2
+
+ %r.3 = lshr i32 %upper, 24
+ %u.3 = and i32 %r.3, u0xff
+ %z.3 = zext i32 %u.3 to i64
+ %s.3 = shl i64 %z.3, 56
+ %o.3 = or i64 %o.2, %s.3
+
+ ret i64 %o.3
+}
----------------
arsenm wrote:
Test vector cases
https://github.com/llvm/llvm-project/pull/147737
More information about the llvm-commits
mailing list