mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2025-02-08 21:32:39 +00:00
implement InstCombine/and-compare.ll:test1. This compiles:
typedef struct { unsigned prefix : 4; unsigned code : 4; unsigned unsigned_p : 4; } tree_common; int foo(tree_common *a, tree_common *b) { return a->code == b->code; } into: _foo: movl 4(%esp), %eax movl 8(%esp), %ecx movl (%eax), %eax xorl (%ecx), %eax # TRUNCATE movb %al, %al shrb $4, %al testb %al, %al sete %al movzbl %al, %eax ret instead of: _foo: movl 8(%esp), %eax movb (%eax), %al shrb $4, %al movl 4(%esp), %ecx movb (%ecx), %cl shrb $4, %cl cmpb %al, %cl sete %al movzbl %al, %eax ret saving one cycle by eliminating a shift. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@31727 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
parent
96dddd969f
commit
9c2328e5a9
@ -4950,6 +4950,32 @@ Instruction *InstCombiner::visitSetCondInst(SetCondInst &I) {
|
||||
return BinaryOperator::create(I.getOpcode(), B,
|
||||
Constant::getNullValue(B->getType()));
|
||||
}
|
||||
|
||||
Value *C, *D;
|
||||
// (X&Z) == (Y&Z) -> (X^Y) & Z == 0
|
||||
if (Op0->hasOneUse() && Op1->hasOneUse() &&
|
||||
match(Op0, m_And(m_Value(A), m_Value(B))) &&
|
||||
match(Op1, m_And(m_Value(C), m_Value(D)))) {
|
||||
Value *X = 0, *Y = 0, *Z = 0;
|
||||
|
||||
if (A == C) {
|
||||
X = B; Y = D; Z = A;
|
||||
} else if (A == D) {
|
||||
X = B; Y = C; Z = A;
|
||||
} else if (B == C) {
|
||||
X = A; Y = D; Z = B;
|
||||
} else if (B == D) {
|
||||
X = A; Y = C; Z = B;
|
||||
}
|
||||
|
||||
if (X) { // Build (X^Y) & Z
|
||||
Op1 = InsertNewInstBefore(BinaryOperator::createXor(X, Y, "tmp"), I);
|
||||
Op1 = InsertNewInstBefore(BinaryOperator::createAnd(Op1, Z, "tmp"), I);
|
||||
I.setOperand(0, Op1);
|
||||
I.setOperand(1, Constant::getNullValue(Op1->getType()));
|
||||
return &I;
|
||||
}
|
||||
}
|
||||
}
|
||||
return Changed ? &I : 0;
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user