rdar://12329730 (defect 2)

Enhancement to InstCombine. Try to catch this opportunity:
  
 ---------------------------------------------------------------
 ((X^C1) >> C2) ^ C3  => (X>>C2) ^ ((C1>>C2)^C3)
  where the subexpression "X ^ C1" has more than one uses, and
  "(X^C1) >> C2" has single use. 
 ---------------------------------------------------------------- 

 Reviewed by Nadav (with minor change per his request).


git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@168615 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Shuxin Yang 2012-11-26 21:44:25 +00:00
parent ec66ac5318
commit b30e256993
2 changed files with 36 additions and 0 deletions

View File

@ -2159,6 +2159,27 @@ Instruction *InstCombiner::visitXor(BinaryOperator &I) {
I.setOperand(1, NewRHS);
return &I;
}
} else if (Op0I->getOpcode() == Instruction::LShr) {
// ((X^C1) >> C2) ^ C3 -> (X>>C2) ^ ((C1>>C2)^C3)
// E1 = "X ^ C1"
BinaryOperator *E1;
ConstantInt *C1;
if (Op0I->hasOneUse() &&
(E1 = dyn_cast<BinaryOperator>(Op0I->getOperand(0))) &&
E1->getOpcode() == Instruction::Xor &&
(C1 = dyn_cast<ConstantInt>(E1->getOperand(1)))) {
// fold (C1 >> C2) ^ C3
ConstantInt *C2 = Op0CI, *C3 = RHS;
APInt FoldConst = C1->getValue().lshr(C2->getValue());
FoldConst ^= C3->getValue();
// Prepare the two operands.
Value *Opnd0 = Builder->CreateLShr(E1->getOperand(0), C2);
Opnd0->takeName(Op0I);
cast<Instruction>(Opnd0)->setDebugLoc(I.getDebugLoc());
Value *FoldVal = ConstantInt::get(Opnd0->getType(), FoldConst);
return BinaryOperator::CreateXor(Opnd0, FoldVal);
}
}
}
}

View File

@ -51,3 +51,18 @@ define i32 @test4(i32 %A, i32 %B) {
; CHECK: %1 = ashr i32 %A, %B
; CHECK: ret i32 %1
}
; defect-2 in rdar://12329730
; (X^C1) >> C2) ^ C3 -> (X>>C2) ^ ((C1>>C2)^C3)
; where the "X" has more than one use
define i32 @test5(i32 %val1) {
test5:
%xor = xor i32 %val1, 1234
%shr = lshr i32 %xor, 8
%xor1 = xor i32 %shr, 1
%add = add i32 %xor1, %xor
ret i32 %add
; CHECK: @test5
; CHECK: lshr i32 %val1, 8
; CHECK: ret
}