[llvm-commits] [PATCH] InstCombine enhancement
Shuxin Yang
shuxin.llvm at gmail.com
Mon Nov 26 13:32:08 PST 2012
Hi, dear all:
This change is trying to catch this optimization opportunity (one
of the two defects reported in rdar://12329730):
-----------------------------------------------------
((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.
------------------------------------------------------
If the "X ^ C1" has only one use, InstCombine will distribute the
">>" operation
in the "X^C1 >> C2", and the entire expression would be eventually
optimized;
however, if "X ^ C1" has multiple uses, InstCombine would give up.
Thanks
Shuxin
-------------- next part --------------
Index: test/Transforms/InstCombine/xor2.ll
===================================================================
--- test/Transforms/InstCombine/xor2.ll (revision 168597)
+++ test/Transforms/InstCombine/xor2.ll (working copy)
@@ -51,3 +51,18 @@
; 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
+}
Index: lib/Transforms/InstCombine/InstCombineAndOrXor.cpp
===================================================================
--- lib/Transforms/InstCombine/InstCombineAndOrXor.cpp (revision 168597)
+++ lib/Transforms/InstCombine/InstCombineAndOrXor.cpp (working copy)
@@ -2159,6 +2159,26 @@
I.setOperand(1, NewRHS);
return &I;
}
+ } else if (Op0I->getOpcode() == Instruction::LShr) {
+ // ((X^C1) >> C2) ^ C3 -> (X>>C2) ^ ((C1>>C2)^C3)
+ BinaryOperator *E1; // E1 = "X ^ C1"
+ 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);
+ }
}
}
}
More information about the llvm-commits
mailing list