Skip to content

Commit 2964a53

Browse files
artagnonregehr
andcommitted
[InstComb] Fold ashr (xor x, y), x -> ashr y, x
Proof: https://alive2.llvm.org/ce/z/yWCmMd Co-authored-by: John Regehr <[email protected]>
1 parent 433b878 commit 2964a53

File tree

2 files changed

+10
-6
lines changed

2 files changed

+10
-6
lines changed

llvm/lib/Transforms/InstCombine/InstCombineShifts.cpp

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1836,6 +1836,11 @@ Instruction *InstCombinerImpl::visitAShr(BinaryOperator &I) {
18361836
return Lshr;
18371837
}
18381838

1839+
// ashr (xor %x, %y), %x --> ashr %y, %x
1840+
Value *Y;
1841+
if (match(Op0, m_Xor(m_Value(X), m_Value(Y))) && Op1 == X)
1842+
return BinaryOperator::CreateAShr(Y, X);
1843+
18391844
// ashr (xor %x, -1), %y --> xor (ashr %x, %y), -1
18401845
if (match(Op0, m_OneUse(m_Not(m_Value(X))))) {
18411846
// Note that we must drop 'exact'-ness of the shift!

llvm/test/Transforms/InstCombine/shift-logic.ll

Lines changed: 5 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -228,8 +228,7 @@ define <2 x i32> @ashr_poison_poison_xor(<2 x i32> %x, <2 x i32> %y) {
228228

229229
define i32 @ashr_xor_operand_match(i32 %x, i32 %y) {
230230
; CHECK-LABEL: @ashr_xor_operand_match(
231-
; CHECK-NEXT: [[SH1:%.*]] = xor i32 [[TMP1:%.*]], [[TMP2:%.*]]
232-
; CHECK-NEXT: [[RET:%.*]] = ashr i32 [[SH1]], [[TMP1]]
231+
; CHECK-NEXT: [[RET:%.*]] = ashr i32 [[Y:%.*]], [[X:%.*]]
233232
; CHECK-NEXT: ret i32 [[RET]]
234233
;
235234
%r = xor i32 %x, %y
@@ -239,10 +238,10 @@ define i32 @ashr_xor_operand_match(i32 %x, i32 %y) {
239238

240239
define i32 @ashr_xor_operand_match_multiuse(i32 %x, i32 %y) {
241240
; CHECK-LABEL: @ashr_xor_operand_match_multiuse(
242-
; CHECK-NEXT: [[R:%.*]] = xor i32 [[X:%.*]], [[Y:%.*]]
243-
; CHECK-NEXT: [[Q:%.*]] = ashr i32 [[R]], [[X]]
244-
; CHECK-NEXT: [[RET:%.*]] = xor i32 [[R]], [[Q]]
245-
; CHECK-NEXT: ret i32 [[RET]]
241+
; CHECK-NEXT: [[Q:%.*]] = ashr i32 [[Y:%.*]], [[X:%.*]]
242+
; CHECK-NEXT: [[RET:%.*]] = xor i32 [[Y]], [[Q]]
243+
; CHECK-NEXT: [[RET1:%.*]] = xor i32 [[RET]], [[X]]
244+
; CHECK-NEXT: ret i32 [[RET1]]
246245
;
247246
%r = xor i32 %x, %y
248247
%q = ashr i32 %r, %x

0 commit comments

Comments
 (0)