[llvm] [InstComb] Fold ashr (xor x, y), x -> ashr y, x (PR #165866)
via llvm-commits
llvm-commits at lists.llvm.org
Fri Oct 31 07:04:57 PDT 2025
llvmbot wrote:
<!--LLVM PR SUMMARY COMMENT-->
@llvm/pr-subscribers-llvm-transforms
Author: Ramkumar Ramachandra (artagnon)
<details>
<summary>Changes</summary>
Proof: https://alive2.llvm.org/ce/z/yWCmMd
---
Full diff: https://github.com/llvm/llvm-project/pull/165866.diff
2 Files Affected:
- (modified) llvm/lib/Transforms/InstCombine/InstCombineShifts.cpp (+5)
- (modified) llvm/test/Transforms/InstCombine/shift-logic.ll (+22)
``````````diff
diff --git a/llvm/lib/Transforms/InstCombine/InstCombineShifts.cpp b/llvm/lib/Transforms/InstCombine/InstCombineShifts.cpp
index 899a3c16554c9..6410a509a48af 100644
--- a/llvm/lib/Transforms/InstCombine/InstCombineShifts.cpp
+++ b/llvm/lib/Transforms/InstCombine/InstCombineShifts.cpp
@@ -1836,6 +1836,11 @@ Instruction *InstCombinerImpl::visitAShr(BinaryOperator &I) {
return Lshr;
}
+ // ashr (xor %x, %y), %x --> ashr %y, %x
+ Value *Y;
+ if (match(Op0, m_Xor(m_Value(X), m_Value(Y))) && Op1 == X)
+ return BinaryOperator::CreateAShr(Y, X);
+
// ashr (xor %x, -1), %y --> xor (ashr %x, %y), -1
if (match(Op0, m_OneUse(m_Not(m_Value(X))))) {
// Note that we must drop 'exact'-ness of the shift!
diff --git a/llvm/test/Transforms/InstCombine/shift-logic.ll b/llvm/test/Transforms/InstCombine/shift-logic.ll
index ab8d98a9523ba..2de2073a183b7 100644
--- a/llvm/test/Transforms/InstCombine/shift-logic.ll
+++ b/llvm/test/Transforms/InstCombine/shift-logic.ll
@@ -186,6 +186,7 @@ define i32 @ashr_xor(i32 %x, i32 %py) {
ret i32 %sh1
}
+
define i32 @shr_mismatch_xor(i32 %x, i32 %y) {
; CHECK-LABEL: @shr_mismatch_xor(
; CHECK-NEXT: [[SH0:%.*]] = ashr i32 [[X:%.*]], 5
@@ -225,6 +226,27 @@ define <2 x i32> @ashr_poison_poison_xor(<2 x i32> %x, <2 x i32> %y) {
ret <2 x i32> %sh1
}
+define i32 @ashr_xor_operand_match(i32 %x, i32 %y) {
+; CHECK-LABEL: @ashr_xor_operand_match(
+; CHECK-NEXT: [[RET:%.*]] = ashr i32 [[SH1:%.*]], [[TMP1:%.*]]
+; CHECK-NEXT: ret i32 [[RET]]
+;
+ %r = xor i32 %x, %y
+ %ret = ashr i32 %r, %x
+ ret i32 %ret
+}
+
+define i32 @ashr_xor_operand_mismtach(i32 %x, i32 %y) {
+; CHECK-LABEL: @ashr_xor_operand_mismtach(
+; CHECK-NEXT: [[R:%.*]] = xor i32 [[X:%.*]], [[Y:%.*]]
+; CHECK-NEXT: [[RET:%.*]] = ashr i32 [[R]], [[Y]]
+; CHECK-NEXT: ret i32 [[RET]]
+;
+ %r = xor i32 %x, %y
+ %ret = ashr i32 %r, %y
+ ret i32 %ret
+}
+
define i32 @lshr_or_extra_use(i32 %x, i32 %y, ptr %p) {
; CHECK-LABEL: @lshr_or_extra_use(
; CHECK-NEXT: [[SH0:%.*]] = lshr i32 [[X:%.*]], 5
``````````
</details>
https://github.com/llvm/llvm-project/pull/165866
More information about the llvm-commits
mailing list