[llvm] [InstCombine] Fold xor(zext(or disjoint X, C1), C2) (PR #214970)
Andreas Jonson via llvm-commits
llvm-commits at lists.llvm.org
Sat Aug 8 09:56:24 PDT 2026
=?utf-8?b?7KGw7JiB7KeEKEpveW91bmdqaW4p?=
Message-ID:
In-Reply-To: <llvm.org/llvm/llvm-project/pull/214970 at github.com>
================
@@ -1664,3 +1664,89 @@ entry:
%or = or <2 x i32> %add, %c
ret <2 x i32> %or
}
+
+; xor(zext(or disjoint X, NarrowC), WideC) ->
+; xor(zext(X), WideC ^ zext(NarrowC))
+
+define i32 @fold_zext_or_disjoint_xor_i8_to_i32(i8 %input) {
+; CHECK-LABEL: @fold_zext_or_disjoint_xor_i8_to_i32(
+; CHECK-NEXT: [[Z:%.*]] = zext i8 [[INPUT:%.*]] to i32
+; CHECK-NEXT: [[R:%.*]] = xor i32 [[Z]], 267
+; CHECK-NEXT: ret i32 [[R]]
+;
+ %or = or disjoint i8 %input, 10
+ %z = zext i8 %or to i32
+ %r = xor i32 %z, 257
+ ret i32 %r
+}
+
+define i64 @fold_zext_or_disjoint_xor_i32_to_i64(i32 %x) {
+; CHECK-LABEL: @fold_zext_or_disjoint_xor_i32_to_i64(
+; CHECK-NEXT: [[Z:%.*]] = zext i32 [[X:%.*]] to i64
+; CHECK-NEXT: [[R:%.*]] = xor i64 [[Z]], 2611923443488327890
+; CHECK-NEXT: ret i64 [[R]]
+;
+ %or = or disjoint i32 %x, 1
+ %z = zext i32 %or to i64
+ %r = xor i64 %z, 2611923443488327891
+ ret i64 %r
+}
+
+define i64 @fold_zext_or_disjoint_xor_nneg(i32 %x) {
+; CHECK-LABEL: @fold_zext_or_disjoint_xor_nneg(
+; CHECK-NEXT: [[TMP1:%.*]] = zext i32 [[X:%.*]] to i64
+; CHECK-NEXT: [[R:%.*]] = xor i64 [[TMP1]], 7640891576939301128
+; CHECK-NEXT: ret i64 [[R]]
+;
+ %or = or disjoint i32 %x, 16842752
+ %z = zext nneg i32 %or to i64
+ %r = xor i64 %z, 7640891576956012808
+ ret i64 %r
+}
+
+define i32 @no_fold_zext_plain_or_xor(i8 %x) {
+; CHECK-LABEL: @no_fold_zext_plain_or_xor(
+; CHECK-NEXT: [[OR:%.*]] = or i8 [[X:%.*]], 2
+; CHECK-NEXT: [[Z:%.*]] = zext i8 [[OR]] to i32
+; CHECK-NEXT: [[R:%.*]] = xor i32 [[Z]], 257
+; CHECK-NEXT: ret i32 [[R]]
+;
+ %or = or i8 %x, 2
+ %z = zext i8 %or to i32
+ %r = xor i32 %z, 257
+ ret i32 %r
+}
+
+define i32 @no_fold_zext_multi_use(i8 %x) {
+; CHECK-LABEL: @no_fold_zext_multi_use(
+; CHECK-NEXT: [[OR:%.*]] = or disjoint i8 [[X:%.*]], 2
+; CHECK-NEXT: [[Z:%.*]] = zext i8 [[OR]] to i32
+; CHECK-NEXT: [[R:%.*]] = xor i32 [[Z]], 257
+; CHECK-NEXT: [[USE:%.*]] = add nuw nsw i32 [[Z]], 1
+; CHECK-NEXT: [[RESULT:%.*]] = add nuw nsw i32 [[R]], [[USE]]
+; CHECK-NEXT: ret i32 [[RESULT]]
+;
+ %or = or disjoint i8 %x, 2
+ %z = zext i8 %or to i32
+ %r = xor i32 %z, 257
+ %use = add i32 %z, 1
----------------
andjo403 wrote:
most common to use a call to a use function for extra uses eg:
call void @use(i8 %a)
https://github.com/llvm/llvm-project/pull/214970
More information about the llvm-commits
mailing list