[llvm] 53a2fd9 - [DAGCombiner] Combine (fshl A, B, S) | (fshr C, D, BW-S) --> (fshl (A|C), (B|D), S) (#180889)
via llvm-commits
llvm-commits at lists.llvm.org
Tue Mar 10 18:53:44 PDT 2026
Author: Craig Topper
Date: 2026-03-10T18:53:40-07:00
New Revision: 53a2fd99aa7d55051db03b6f389814c6b6741502
URL: https://github.com/llvm/llvm-project/commit/53a2fd99aa7d55051db03b6f389814c6b6741502
DIFF: https://github.com/llvm/llvm-project/commit/53a2fd99aa7d55051db03b6f389814c6b6741502.diff
LOG: [DAGCombiner] Combine (fshl A, B, S) | (fshr C, D, BW-S) --> (fshl (A|C), (B|D), S) (#180889)
This is similar to the FSHL/FSHR handling in
hoistLogicOpWithSameOpcodeHands.
Here the opcodes aren't exactly the same, but the operations are
equivalent.
Fixes regressions from #180888
Added:
Modified:
llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp
llvm/test/CodeGen/X86/icmp-shift-opt.ll
Removed:
################################################################################
diff --git a/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp b/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp
index a2353fe2a2993..8c18d8bb625be 100644
--- a/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp
+++ b/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp
@@ -8535,6 +8535,24 @@ static SDValue visitORCommutative(SelectionDAG &DAG, SDValue N0, SDValue N1,
}
}
+ // (fshl A, B, S0) | (fshr C, D, S1) --> fshl (A|C), (B|D), S0
+ // iff S0 + S1 == bitwidth(S1)
+ if (N0.getOpcode() == ISD::FSHL && N1.getOpcode() == ISD::FSHR &&
+ N0.hasOneUse() && N1.hasOneUse()) {
+ auto *S0 = dyn_cast<ConstantSDNode>(N0.getOperand(2));
+ auto *S1 = dyn_cast<ConstantSDNode>(N1.getOperand(2));
+ if (S0 && S1 && S0->getZExtValue() < BW && S1->getZExtValue() < BW &&
+ S0->getZExtValue() == (BW - S1->getZExtValue())) {
+ SDValue A = N0.getOperand(0);
+ SDValue B = N0.getOperand(1);
+ SDValue C = N1.getOperand(0);
+ SDValue D = N1.getOperand(1);
+ SDValue NewLHS = DAG.getNode(ISD::OR, DL, VT, A, C);
+ SDValue NewRHS = DAG.getNode(ISD::OR, DL, VT, B, D);
+ return DAG.getNode(ISD::FSHL, DL, VT, NewLHS, NewRHS, N0.getOperand(2));
+ }
+ }
+
// Attempt to match a legalized build_pair-esque pattern:
// or(shl(aext(Hi),BW/2),zext(Lo))
SDValue Lo, Hi;
diff --git a/llvm/test/CodeGen/X86/icmp-shift-opt.ll b/llvm/test/CodeGen/X86/icmp-shift-opt.ll
index 7ba7f6212d517..0296c2a011e25 100644
--- a/llvm/test/CodeGen/X86/icmp-shift-opt.ll
+++ b/llvm/test/CodeGen/X86/icmp-shift-opt.ll
@@ -83,14 +83,12 @@ define i1 @opt_setcc_srl_eq_zero(i128 %a) nounwind {
; X86-NEXT: movl %esp, %ebp
; X86-NEXT: andl $-16, %esp
; X86-NEXT: subl $16, %esp
-; X86-NEXT: movl 16(%ebp), %eax
+; X86-NEXT: movl 8(%ebp), %eax
; X86-NEXT: movl 12(%ebp), %ecx
+; X86-NEXT: shrl $17, %eax
; X86-NEXT: orl 20(%ebp), %ecx
-; X86-NEXT: movl %eax, %edx
-; X86-NEXT: shldl $15, %ecx, %edx
-; X86-NEXT: orl 8(%ebp), %eax
-; X86-NEXT: shrdl $17, %ecx, %eax
-; X86-NEXT: orl %edx, %eax
+; X86-NEXT: orl 16(%ebp), %ecx
+; X86-NEXT: orl %eax, %ecx
; X86-NEXT: sete %al
; X86-NEXT: movl %ebp, %esp
; X86-NEXT: popl %ebp
@@ -114,14 +112,12 @@ define i1 @opt_setcc_srl_ne_zero(i128 %a) nounwind {
; X86-NEXT: movl %esp, %ebp
; X86-NEXT: andl $-16, %esp
; X86-NEXT: subl $16, %esp
-; X86-NEXT: movl 16(%ebp), %eax
+; X86-NEXT: movl 8(%ebp), %eax
; X86-NEXT: movl 12(%ebp), %ecx
+; X86-NEXT: shrl $17, %eax
; X86-NEXT: orl 20(%ebp), %ecx
-; X86-NEXT: movl %eax, %edx
-; X86-NEXT: shldl $15, %ecx, %edx
-; X86-NEXT: orl 8(%ebp), %eax
-; X86-NEXT: shrdl $17, %ecx, %eax
-; X86-NEXT: orl %edx, %eax
+; X86-NEXT: orl 16(%ebp), %ecx
+; X86-NEXT: orl %eax, %ecx
; X86-NEXT: setne %al
; X86-NEXT: movl %ebp, %esp
; X86-NEXT: popl %ebp
More information about the llvm-commits
mailing list