================
@@ -1488,6 +1488,61 @@ static bool SinkCast(CastInst *CI) {
return MadeChange;
}
+/// Hoists bitcasts to the source block to reduce register pressure
+static bool optimizeBitCast(BitCastInst *BCI, const TargetLowering &TLI,
+ const DataLayout &DL) {
+ auto *SrcInst = dyn_cast<Instruction>(BCI->getOperand(0));
+ if (!SrcInst || SrcInst->getParent() == BCI->getParent() ||
+ SrcInst->isTerminator())
+ return false;
+
+ EVT SrcVT = TLI.getValueType(DL, SrcInst->getType());
+ EVT DestVT = TLI.getValueType(DL, BCI->getType());
+
+ // Bail out on scalable vectors and illegal destination types
+ if (SrcVT.isScalableVector() || DestVT.isScalableVector() ||
+ !TLI.isTypeLegal(DestVT))
+ return false;
+
+ // Only hoist if it reduces physical register count
+ if (TLI.getNumRegisters(BCI->getContext(), SrcVT) <=
+ TLI.getNumRegisters(BCI->getContext(), DestVT))
+ return false;
+
+ // Prevent large cross-domain scalar hoists
+ Type *DestTy = BCI->getType();
+ Type *SrcTy = SrcInst->getType();
+ bool IsCrossDomain = DestTy->isFPOrFPVectorTy() != SrcTy->isFPOrFPVectorTy();
+ bool IsLargeScalar = !DestTy->isVectorTy() &&
+ DL.getTypeSizeInBits(DestTy).getFixedValue() > 64;
+ if (IsCrossDomain && IsLargeScalar)
+ return false;
+
+ // SelectionDAG Guard to prevent breaking atomic loop layout
+ auto IsAtomic = [](const Value *V) {
+ const auto *I = dyn_cast<Instruction>(V);
+ return I && I->isAtomic();
+ };
----------------
houngkoungting wrote:
Hi @RKSimon,
Sorry for the delay due to the typhoon. I took some time to isolate the exact
impact of dropping this atomic guard on "X86/atomic-non-integer.ll".
Without this blocker, the middle-end prematurely hoists the implicit bitcast
logic.
32-bit x86 targets ("X86-SSE1" and "X86-NOSSE") severely lack 64-bit GPRs.
Also, the hardware rigidly binds "lock cmpxchg8b" to the "EDX:EAX" register
pair.
This premature hoisting creates severe register pressure, breaks the liveness
chain, and results in bad register allocation.
As a result, the backend instruction scheduler is forced to drag the entire x87
stack transfers ("fstp/fldl") and memory stores ("movl") directly into the hot
retry loop body (".LBB8_1") across both subtargets:
```
@@ -440,15 +440,17 @@ define double @exchange_double(ptr %fptr, double %x) {
; X86-SSE1-NEXT: movl {{[0-9]+}}(%esp), %ecx
; X86-SSE1-NEXT: movl (%esi), %eax
; X86-SSE1-NEXT: movl 4(%esi), %edx
+; X86-SSE1-NEXT: fldz
; X86-SSE1-NEXT: .p2align 4
; X86-SSE1-NEXT: .LBB8_1: # %atomicrmw.start
; X86-SSE1-NEXT: # =>This Inner Loop Header: Depth=1
+; X86-SSE1-NEXT: fstp %st(0)
; X86-SSE1-NEXT: lock cmpxchg8b (%esi)
-; X86-SSE1-NEXT: jne .LBB8_1
-; X86-SSE1-NEXT: # %bb.2: # %atomicrmw.end
-; X86-SSE1-NEXT: movl %eax, (%esp)
; X86-SSE1-NEXT: movl %edx, {{[0-9]+}}(%esp)
+; X86-SSE1-NEXT: movl %eax, (%esp) # Injected inside loop (RAW!!!!!!)
; X86-SSE1-NEXT: fldl (%esp)
+; X86-SSE1-NEXT: jne .LBB8_1 # Loop boundary expanded down here
+; X86-SSE1-NEXT: # %bb.2: # %atomicrmw.end
; X86-SSE1-NEXT: addl $12, %esp
; X86-SSE1-NEXT: .cfi_def_cfa_offset 12
; X86-SSE1-NEXT: popl %esi
https://github.com/llvm/llvm-project/pull/207568
_______________________________________________
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits