[llvm] r327365 - bpf: Tighten subregister definition check

Yonghong Song via llvm-commits llvm-commits at lists.llvm.org
Mon Mar 12 23:47:01 PDT 2018


Author: yhs
Date: Mon Mar 12 23:47:00 2018
New Revision: 327365

URL: http://llvm.org/viewvc/llvm-project?rev=327365&view=rev
Log:
bpf: Tighten subregister definition check

The current subregister definition check stops after the MOV_32_64
instruction.

This means we are thinking all the following instruction sequences
are safe to be eliminated:

  MOV_32_64 rB, wA
  SLL_ri    rB, rB, 32
  SRL_ri    rB, rB, 32

However, this is *not* true. The source subregister wA of MOV_32_64 could
come from a implicit truncation of 64-bit register in which case the high
bits of the 64-bit register is not zeroed, therefore we can't eliminate
above sequence.

For example, for i32_val, we shouldn't do the elimination:

  long long bar ();

  int foo (int b, int c)
  {
    unsigned int i32_val = (unsigned int) bar();

    if (i32_val < 10)
      return b;
    else
      return c;
  }

Signed-off-by: Jiong Wang <jiong.wang at netronome.com>
Signed-off-by: Yonghong Song <yhs at fb.com>

Modified:
    llvm/trunk/lib/Target/BPF/BPFMIPeephole.cpp
    llvm/trunk/test/CodeGen/BPF/32-bit-subreg-peephole.ll

Modified: llvm/trunk/lib/Target/BPF/BPFMIPeephole.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/BPF/BPFMIPeephole.cpp?rev=327365&r1=327364&r2=327365&view=diff
==============================================================================
--- llvm/trunk/lib/Target/BPF/BPFMIPeephole.cpp (original)
+++ llvm/trunk/lib/Target/BPF/BPFMIPeephole.cpp Mon Mar 12 23:47:00 2018
@@ -96,6 +96,24 @@ MachineInstr *BPFMIPeephole::getInsnDefZ
       Insn->getOpcode() != BPF::MOV_32_64)
     return nullptr;
 
+  Insn = MRI->getVRegDef(Insn->getOperand(1).getReg());
+  if (!Insn || Insn->isPHI())
+    return nullptr;
+
+  if (Insn->getOpcode() == BPF::COPY) {
+    MachineOperand &opnd = Insn->getOperand(1);
+
+    if (!opnd.isReg())
+      return nullptr;
+
+    unsigned Reg = opnd.getReg();
+    if ((TargetRegisterInfo::isVirtualRegister(Reg) &&
+         MRI->getRegClass(Reg) == &BPF::GPRRegClass) ||
+        (TargetRegisterInfo::isPhysicalRegister(Reg) &&
+         BPF::GPRRegClass.contains(Reg)))
+      return nullptr;
+  }
+
   return Insn;
 }
 

Modified: llvm/trunk/test/CodeGen/BPF/32-bit-subreg-peephole.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/BPF/32-bit-subreg-peephole.ll?rev=327365&r1=327364&r2=327365&view=diff
==============================================================================
--- llvm/trunk/test/CodeGen/BPF/32-bit-subreg-peephole.ll (original)
+++ llvm/trunk/test/CodeGen/BPF/32-bit-subreg-peephole.ll Mon Mar 12 23:47:00 2018
@@ -14,7 +14,20 @@
 ;     return c;
 ;   else
 ;     return d;
-;}
+; }
+;
+; long long bar ();
+;
+; int foo (int b, int c)
+; {
+;   unsigned int i32_val = (unsigned int) bar();
+;
+;   if (i32_val < 10)
+;     return b;
+;   else
+;     return c;
+; }
+
 ; Function Attrs: norecurse nounwind readnone
 define dso_local i64 @select_u(i32 %a, i32 %b, i64 %c, i64 %d) local_unnamed_addr #0 {
 ; CHECK-LABEL: select_u:
@@ -38,3 +51,21 @@ entry:
 ; CHECK: if r{{[0-9]+}} s{{<|>}} r{{[0-9]+}} goto
   ret i64 %c.d
 }
+
+; Function Attrs: nounwind
+define dso_local i32 @foo(i32 %b, i32 %c) local_unnamed_addr #0 {
+; CHECK-LABEL: foo:
+entry:
+  %call = tail call i64 bitcast (i64 (...)* @bar to i64 ()*)() #2
+  %conv = trunc i64 %call to i32
+  %cmp = icmp ult i32 %conv, 10
+; The shifts can't be optimized out because %call comes from function call
+; returning i64 so the high bits might be valid.
+; CHECK: r{{[0-9]+}} <<= 32
+; CHECK-NEXT: r{{[0-9]+}} >>= 32
+  %b.c = select i1 %cmp, i32 %b, i32 %c
+; CHECK: if r{{[0-9]+}} {{<|>}} {{[0-9]+}} goto
+  ret i32 %b.c
+}
+
+declare dso_local i64 @bar(...) local_unnamed_addr #1




More information about the llvm-commits mailing list