[llvm] [DAG][X86]added shrd in combineor for bzhiq+shlq+or (PR #125734)

via llvm-commits llvm-commits at lists.llvm.org
Tue Feb 4 10:12:07 PST 2025


llvmbot wrote:


<!--LLVM PR SUMMARY COMMENT-->

@llvm/pr-subscribers-backend-x86

Author: shalininikhil (shalini-nik)

<details>
<summary>Changes</summary>



---
Full diff: https://github.com/llvm/llvm-project/pull/125734.diff


2 Files Affected:

- (modified) llvm/lib/Target/X86/X86ISelLowering.cpp (+29) 
- (added) llvm/test/CodeGen/X86/shrdq-to-insert-into-bitfield.ll (+18) 


``````````diff
diff --git a/llvm/lib/Target/X86/X86ISelLowering.cpp b/llvm/lib/Target/X86/X86ISelLowering.cpp
index a956074e50d86f7..395c0f5504d1b78 100644
--- a/llvm/lib/Target/X86/X86ISelLowering.cpp
+++ b/llvm/lib/Target/X86/X86ISelLowering.cpp
@@ -51887,6 +51887,35 @@ static SDValue combineOr(SDNode *N, SelectionDAG &DAG,
     }
   }
 
+  if (N0.getOpcode() == ISD::SHL || N1.getOpcode() == ISD::SHL){
+    SDValue SHL = (N0.getOpcode() == ISD::SHL) ? N0 : N1;
+    SDValue OtherOp = (N0.getOpcode() == ISD::SHL) ? N1 : N0;
+    
+    if (OtherOp.getOpcode() == ISD::AND) {
+      SDValue andop = OtherOp;
+      
+      if(andop.getOperand(0).getOpcode()==ISD::Constant||andop.getOperand(1).getOpcode()==ISD::Constant){
+              
+              SDValue constOp = andop.getOperand(0).getOpcode()==ISD::Constant ? andop.getOperand(0): andop.getOperand(1);
+              SDValue valueOp = andop.getOperand(0).getOpcode()==ISD::Constant ? andop.getOperand(1): andop.getOperand(0);
+              auto *ConstRHS = dyn_cast<ConstantSDNode>(constOp);
+              uint64_t maskValue = ConstRHS->getZExtValue();
+              auto *ConstSHL = dyn_cast<ConstantSDNode>(SHL.getOperand(1));
+              uint64_t shiftValue = ConstSHL->getZExtValue();
+              
+              if((((uint64_t)1<<shiftValue)-1)==maskValue){
+                      unsigned numbits = SHL.getScalarValueSizeInBits();
+                      unsigned newshift=numbits-shiftValue;
+                      
+                      SDValue newSHL = DAG.getNode(ISD::SHL,dl,VT,valueOp,DAG.getConstant(newshift, dl, MVT::i8));
+                      SDValue R = DAG.getNode(ISD::FSHR,dl,VT,
+                                    SHL.getOperand(0),newSHL,DAG.getConstant(newshift, dl, MVT::i8));
+                      return R;
+            }
+          }
+      }
+  }
+  
   if (SDValue SetCC = combineAndOrForCcmpCtest(N, DAG, DCI, Subtarget))
     return SetCC;
 
diff --git a/llvm/test/CodeGen/X86/shrdq-to-insert-into-bitfield.ll b/llvm/test/CodeGen/X86/shrdq-to-insert-into-bitfield.ll
new file mode 100644
index 000000000000000..cc205ee145d88c8
--- /dev/null
+++ b/llvm/test/CodeGen/X86/shrdq-to-insert-into-bitfield.ll
@@ -0,0 +1,18 @@
+; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
+; RUN: llc -O3 < %s | FileCheck %s
+
+define dso_local i64 @updateTop10Bits(i64 noundef %A, i64 noundef %B) local_unnamed_addr #0 {
+; CHECK-LABEL: updateTop10Bits:
+; CHECK:       # %bb.0:
+; CHECK-NEXT:    movq	%rdi, %rax
+; CHECK-NEXT:    shlq	$10, %rax
+; CHECK-NEXT:    shrdq	$10, %rsi, %rax
+; CHECK-NEXT:    retq
+entry:
+  %and = and i64 %A, 18014398509481983
+  %shl = shl i64 %B, 54
+  %or = or disjoint i64 %shl, %and
+  ret i64 %or
+}
+
+attributes #0 = { mustprogress nofree norecurse nosync nounwind willreturn memory(none) uwtable "min-legal-vector-width"="0" "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-cpu"="skylake" "target-features"="+adx,+aes,+avx,+avx2,+bmi,+bmi2,+clflushopt,+cmov,+crc32,+cx16,+cx8,+f16c,+fma,+fsgsbase,+fxsr,+invpcid,+lzcnt,+mmx,+movbe,+pclmul,+popcnt,+prfchw,+rdrnd,+rdseed,+sahf,+sgx,+sse,+sse2,+sse3,+sse4.1,+sse4.2,+ssse3,+x87,+xsave,+xsavec,+xsaveopt,+xsaves" }
\ No newline at end of file

``````````

</details>


https://github.com/llvm/llvm-project/pull/125734


More information about the llvm-commits mailing list