[PATCH] D103922: [X86FixupLEAs] Sub register usage of LEA dest should block LEA/SUB optimization

Guozhi Wei via Phabricator via llvm-commits llvm-commits at lists.llvm.org
Tue Jun 8 12:11:42 PDT 2021


Carrot created this revision.
Carrot added reviewers: RKSimon, craig.topper, lebedev.ri, mkazantsev.
Herald added subscribers: pengfei, hiraditya.
Carrot requested review of this revision.
Herald added a project: LLVM.
Herald added a subscriber: llvm-commits.

In function searchALUInst, sub register usage of LEA dest should also block LEA/SUB optimization, otherwise the sub register usage gets an undefined value.

This patch fixes https://bugs.llvm.org/show_bug.cgi?id=50615.


Repository:
  rG LLVM Github Monorepo

https://reviews.llvm.org/D103922

Files:
  llvm/lib/Target/X86/X86FixupLEAs.cpp
  llvm/test/CodeGen/X86/lea-opt2.ll


Index: llvm/test/CodeGen/X86/lea-opt2.ll
===================================================================
--- llvm/test/CodeGen/X86/lea-opt2.ll
+++ llvm/test/CodeGen/X86/lea-opt2.ll
@@ -182,3 +182,31 @@
   %sub1 = sub i64 %ld, %b
   ret i64 %sub1
 }
+
+; The sub register usage of lea dest should block the transformation.
+define void @test9(i64 %p, i64 %s) {
+; CHECK-LABEL: test9:
+; CHECK:       # %bb.0: # %entry
+; CHECK-NEXT:    leaq (%rsi,%rdi), %rax
+; CHECK-NEXT:    xorl %ecx, %ecx
+; CHECK-NEXT:    testl $4095, %eax # imm = 0xFFF
+; CHECK-NEXT:    setne %cl
+; CHECK-NEXT:    shlq $12, %rcx
+; CHECK-NEXT:    addq %rax, %rcx
+; CHECK-NEXT:    andq $-4096, %rcx # imm = 0xF000
+; CHECK-NEXT:    addq %rcx, %rdi
+; CHECK-NEXT:    jmp bar at PLT # TAILCALL
+entry:
+  %add = add i64 %s, %p
+  %rem = and i64 %add, 4095
+  %cmp.not = icmp eq i64 %rem, 0
+  %add18 = select i1 %cmp.not, i64 0, i64 4096
+  %div9 = add i64 %add18, %add
+  %mul = and i64 %div9, -4096
+  %add2 = add i64 %mul, %p
+  tail call void @bar(i64 %add2, i64 %s)
+  ret void
+}
+
+declare void @bar(i64, i64)
+
Index: llvm/lib/Target/X86/X86FixupLEAs.cpp
===================================================================
--- llvm/lib/Target/X86/X86FixupLEAs.cpp
+++ llvm/lib/Target/X86/X86FixupLEAs.cpp
@@ -418,26 +418,30 @@
     // Check if the lea dest register is used in an add/sub instruction only.
     for (unsigned I = 0, E = CurInst->getNumOperands(); I != E; ++I) {
       MachineOperand &Opnd = CurInst->getOperand(I);
-      if (Opnd.isReg() && Opnd.getReg() == DestReg) {
-        if (Opnd.isDef() || !Opnd.isKill())
+      if (Opnd.isReg()) {
+        if (Opnd.getReg() == DestReg) {
+          if (Opnd.isDef() || !Opnd.isKill())
+            return MachineBasicBlock::iterator();
+
+          unsigned AluOpcode = CurInst->getOpcode();
+          if (AluOpcode != AddOpcode && AluOpcode != SubOpcode)
+            return MachineBasicBlock::iterator();
+
+          MachineOperand &Opnd2 = CurInst->getOperand(3 - I);
+          MachineOperand AluDest = CurInst->getOperand(0);
+          if (Opnd2.getReg() != AluDest.getReg())
+            return MachineBasicBlock::iterator();
+
+          // X - (Y + Z) may generate different flags than (X - Y) - Z when
+          // there is overflow. So we can't change the alu instruction if the
+          // flags register is live.
+          if (!CurInst->registerDefIsDead(X86::EFLAGS, TRI))
+            return MachineBasicBlock::iterator();
+
+          return CurInst;
+        }
+        if (TRI->regsOverlap(DestReg, Opnd.getReg()))
           return MachineBasicBlock::iterator();
-
-        unsigned AluOpcode = CurInst->getOpcode();
-        if (AluOpcode != AddOpcode && AluOpcode != SubOpcode)
-          return MachineBasicBlock::iterator();
-
-        MachineOperand &Opnd2 = CurInst->getOperand(3 - I);
-        MachineOperand AluDest = CurInst->getOperand(0);
-        if (Opnd2.getReg() != AluDest.getReg())
-          return MachineBasicBlock::iterator();
-
-        // X - (Y + Z) may generate different flags than (X - Y) - Z when there
-        // is overflow. So we can't change the alu instruction if the flags
-        // register is live.
-        if (!CurInst->registerDefIsDead(X86::EFLAGS, TRI))
-          return MachineBasicBlock::iterator();
-
-        return CurInst;
       }
     }
 


-------------- next part --------------
A non-text attachment was scrubbed...
Name: D103922.350680.patch
Type: text/x-patch
Size: 3360 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20210608/4a0d4750/attachment.bin>


More information about the llvm-commits mailing list