[llvm-dev] Weaker (more general) precondition for bit-tests in InstructionSimplify

David Menendez via llvm-dev llvm-dev at lists.llvm.org
Sun Mar 12 18:41:15 PDT 2017


Hello everyone,

We have developed a tool for inferring preconditions for LLVM peephole
optimizations expressed in Alive. Our prototype has found weaker
(more general) preconditions for several optimizations in the Alive suite.
We were able to trace several back to LLVM's InstCombine and
InstructionSimplify stages in the SVN head (r297512), and have identified
a good candidate for weakening in LLVM.

The details of our approach are available in the technical report at
http://export.arxiv.org/abs/1611.05980

Our prototype is available in the Alive-NJ github
at https://github.com/rutgers-apl/alive-nj/

The candidate we have found is in the function simplifySelectBitTest in
InstructionSimplify. The relevant code is:

  // (X & Y) == 0 ? X & ~Y : X  --> X
  // (X & Y) != 0 ? X & ~Y : X  --> X & ~Y
  if (FalseVal == X && match(TrueVal, m_And(m_Specific(X), m_APInt(C))) &&
      *Y == ~*C)
    return TrueWhenUnset ? FalseVal : TrueVal;

  // (X & Y) == 0 ? X : X & ~Y  --> X & ~Y
  // (X & Y) != 0 ? X : X & ~Y  --> X
  if (TrueVal == X && match(FalseVal, m_And(m_Specific(X), m_APInt(C))) &&
      *Y == ~*C)
    return TrueWhenUnset ? FalseVal : TrueVal;

simplifySelectBitTest is called in six different contexts, so this can be 
expressed as 12 optimizations in Alive.

In all 12 cases, the precondition *Y == ~*C can be relaxed to
(*Y | *C).isAllOnesValue().

Alive verifies that the optimization is valid with the weaker
precondition in all 12 cases. 

For reference, Alive version of the optimizations with the current
precondition:

	Name: bittestand-1
	Pre: C1 == ~C2
	%l = and %X, C1
	%c = icmp eq %l, 0
	%t = and %X, C2
	%r = select %c, %t, %X
	=>
	%r = %X

	Name: bittestand-2
	Pre: C1 == ~C2
	%l = and %X, C1
	%c = icmp eq %l, 0
	%f = and %X, C2
	%r = select %c, %X, %f
	=>
	%r = %f

	Name: bittestand-3
	Pre: C1 == ~C2
	%l = and %X, C1
	%c = icmp ne %l, 0
	%t = and %X, C2
	%r = select %c, %t, %X
	=>
	%r = %t

	Name: bittestand-4
	Pre: C1 == ~C2
	%l = and %X, C1
	%c = icmp ne %l, 0
	%f = and %X, C2
	%r = select %c, %X, %f
	=>
	%r = %X

	Name: bittestand-5
	Pre: C1 == ~C2
	%l = trunc %X
	%c = icmp slt %l, 0
	%t = and %X, C2
	%r = select %c, %t, %X
	=>
	C1 = 1 << (width(%l) - 1)
	%r = %t

	Name: bittestand-6
	Pre: C1 == ~C2
	%l = trunc %X
	%c = icmp slt %l, 0
	%f = and %X, C2
	%r = select %c, %X, %f
	=>
	C1 = 1 << (width(%l) - 1)
	%r = %X

	Name: bittestand-7
	Pre: C1 == ~C2
	%c = icmp slt %X, 0
	%t = and %X, C2
	%r = select %c, %t, %X
	=>
	C1 = 1 << (width(%r) - 1)
	%r = %t

	Name: bittestand-8
	Pre: C1 == ~C2
	%c = icmp slt %X, 0
	%f = and %X, C2
	%r = select %c, %X, %f
	=>
	C1 = 1 << (width(%r) - 1)
	%r = %X

	Name: bittestand-9
	Pre: C1 == ~C2
	%l = trunc %X
	%c = icmp sgt %l, -1
	%t = and %X, C2
	%r = select %c, %t, %X
	=>
	C1 = 1 << (width(%l)-1)
	%r = %X

	Name: bittestand-10
	Pre: C1 == ~C2
	%l = trunc %X
	%c = icmp sgt %l, -1
	%f = and %X, C2
	%r = select %c, %X, %f
	=>
	C1 = 1 << (width(%l)-1)
	%r = %f

	Name: bittestand-11
	Pre: C1 == ~C2
	%c = icmp sgt %X, -1
	%t = and %X, C2
	%r = select %c, %t, %X
	=>
	C1 = 1 << (width(%r) - 1)
	%r = %X

	Name: bittestand-12
	Pre: C1 == ~C2
	%c = icmp sgt %X, -1
	%f = and %X, C2
	%r = select %c, %X, %f
	=>
	C1 = 1 << (width(%r) - 1)
	%r = %f


And the optimizations with the weaker precondition:

	Name: bittestand-1
	Pre: C1 | C2 == -1
	%l = and %X, C1
	%c = icmp eq %l, 0
	%t = and %X, C2
	%r = select %c, %t, %X
	=>
	%r = %X

	Name: bittestand-2
	Pre: C1 | C2 == -1
	%l = and %X, C1
	%c = icmp eq %l, 0
	%f = and %X, C2
	%r = select %c, %X, %f
	=>
	%r = %f

	Name: bittestand-3
	Pre: C1 | C2 == -1
	%l = and %X, C1
	%c = icmp ne %l, 0
	%t = and %X, C2
	%r = select %c, %t, %X
	=>
	%r = %t

	Name: bittestand-4
	Pre: C1 | C2 == -1
	%l = and %X, C1
	%c = icmp ne %l, 0
	%f = and %X, C2
	%r = select %c, %X, %f
	=>
	%r = %X

	Name: bittestand-5
	Pre: C1 | C2 == -1
	%l = trunc %X
	%c = icmp slt %l, 0
	%t = and %X, C2
	%r = select %c, %t, %X
	=>
	C1 = 1 << (width(%l) - 1)
	%r = %t

	Name: bittestand-6
	Pre: C1 | C2 == -1
	%l = trunc %X
	%c = icmp slt %l, 0
	%f = and %X, C2
	%r = select %c, %X, %f
	=>
	C1 = 1 << (width(%l) - 1)
	%r = %X

	Name: bittestand-7
	Pre: C1 | C2 == -1
	%c = icmp slt %X, 0
	%t = and %X, C2
	%r = select %c, %t, %X
	=>
	C1 = 1 << (width(%r) - 1)
	%r = %t

	Name: bittestand-8
	Pre: C1 | C2 == -1
	%c = icmp slt %X, 0
	%f = and %X, C2
	%r = select %c, %X, %f
	=>
	C1 = 1 << (width(%r) - 1)
	%r = %X

	Name: bittestand-9
	Pre: C1 | C2 == -1
	%l = trunc %X
	%c = icmp sgt %l, -1
	%t = and %X, C2
	%r = select %c, %t, %X
	=>
	C1 = 1 << (width(%l)-1)
	%r = %X

	Name: bittestand-10
	Pre: C1 | C2 == -1
	%l = trunc %X
	%c = icmp sgt %l, -1
	%f = and %X, C2
	%r = select %c, %X, %f
	=>
	C1 = 1 << (width(%l)-1)
	%r = %f

	Name: bittestand-11
	Pre: C1 | C2 == -1
	%c = icmp sgt %X, -1
	%t = and %X, C2
	%r = select %c, %t, %X
	=>
	C1 = 1 << (width(%r) - 1)
	%r = %X

	Name: bittestand-12
	Pre: C1 | C2 == -1
	%c = icmp sgt %X, -1
	%f = and %X, C2
	%r = select %c, %X, %f
	=>
	C1 = 1 << (width(%r) - 1)
	%r = %f

-- 
David Menendez <davemm at cs.rutgers.edu>
Rutgers University
Architecture and Programming Languages Lab



More information about the llvm-dev mailing list