Skip to content

Commit 68c5d46

Browse files
austin880625goldsteinn
authored andcommitted
[InstCombine] Improve bitreverse optimization
This patch utilizes the helper function implemented in D149699 and thus folds the following cases: ``` bitreverse(logic_op(x, bitreverse(y))) -> logic_op(bitreverse(x), y) bitreverse(logic_op(bitreverse(x), y)) -> logic_op(x, bitreverse(y)) bitreverse(logic_op(bitreverse(x), bitreverse(y))) -> logic_op(x, y) in multiuse case ``` Reviewed By: goldstein.w.n, RKSimon Differential Revision: https://reviews.llvm.org/D151246
1 parent 1d1f7ee commit 68c5d46

File tree

2 files changed

+29
-33
lines changed

2 files changed

+29
-33
lines changed

llvm/lib/Transforms/InstCombine/InstCombineCalls.cpp

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1709,15 +1709,21 @@ Instruction *InstCombinerImpl::visitCallInst(CallInst &CI) {
17091709
break;
17101710
}
17111711
case Intrinsic::bitreverse: {
1712+
Value *IIOperand = II->getArgOperand(0);
17121713
// bitrev (zext i1 X to ?) --> X ? SignBitC : 0
17131714
Value *X;
1714-
if (match(II->getArgOperand(0), m_ZExt(m_Value(X))) &&
1715+
if (match(IIOperand, m_ZExt(m_Value(X))) &&
17151716
X->getType()->isIntOrIntVectorTy(1)) {
17161717
Type *Ty = II->getType();
17171718
APInt SignBit = APInt::getSignMask(Ty->getScalarSizeInBits());
17181719
return SelectInst::Create(X, ConstantInt::get(Ty, SignBit),
17191720
ConstantInt::getNullValue(Ty));
17201721
}
1722+
1723+
if (Instruction *crossLogicOpFold =
1724+
foldBitOrderCrossLogicOp<Intrinsic::bitreverse>(IIOperand, Builder))
1725+
return crossLogicOpFold;
1726+
17211727
break;
17221728
}
17231729
case Intrinsic::bswap: {

llvm/test/Transforms/InstCombine/bitreverse.ll

Lines changed: 22 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -378,10 +378,9 @@ define i64 @PR59897(i1 %X1_2) {
378378

379379
define i16 @rev_xor_lhs_rev16(i16 %a, i16 %b) #0 {
380380
; CHECK-LABEL: @rev_xor_lhs_rev16(
381-
; CHECK-NEXT: [[TMP1:%.*]] = tail call i16 @llvm.bitreverse.i16(i16 [[A:%.*]])
382-
; CHECK-NEXT: [[TMP2:%.*]] = xor i16 [[TMP1]], [[B:%.*]]
383-
; CHECK-NEXT: [[TMP3:%.*]] = tail call i16 @llvm.bitreverse.i16(i16 [[TMP2]])
384-
; CHECK-NEXT: ret i16 [[TMP3]]
381+
; CHECK-NEXT: [[TMP1:%.*]] = call i16 @llvm.bitreverse.i16(i16 [[B:%.*]])
382+
; CHECK-NEXT: [[TMP2:%.*]] = xor i16 [[TMP1]], [[A:%.*]]
383+
; CHECK-NEXT: ret i16 [[TMP2]]
385384
;
386385
%1 = tail call i16 @llvm.bitreverse.i16(i16 %a)
387386
%2 = xor i16 %1, %b
@@ -391,10 +390,9 @@ define i16 @rev_xor_lhs_rev16(i16 %a, i16 %b) #0 {
391390

392391
define i32 @rev_and_rhs_rev32(i32 %a, i32 %b) #0 {
393392
; CHECK-LABEL: @rev_and_rhs_rev32(
394-
; CHECK-NEXT: [[TMP1:%.*]] = tail call i32 @llvm.bitreverse.i32(i32 [[B:%.*]])
395-
; CHECK-NEXT: [[TMP2:%.*]] = and i32 [[TMP1]], [[A:%.*]]
396-
; CHECK-NEXT: [[TMP3:%.*]] = tail call i32 @llvm.bitreverse.i32(i32 [[TMP2]])
397-
; CHECK-NEXT: ret i32 [[TMP3]]
393+
; CHECK-NEXT: [[TMP1:%.*]] = call i32 @llvm.bitreverse.i32(i32 [[A:%.*]])
394+
; CHECK-NEXT: [[TMP2:%.*]] = and i32 [[TMP1]], [[B:%.*]]
395+
; CHECK-NEXT: ret i32 [[TMP2]]
398396
;
399397
%1 = tail call i32 @llvm.bitreverse.i32(i32 %b)
400398
%2 = and i32 %a, %1
@@ -404,10 +402,9 @@ define i32 @rev_and_rhs_rev32(i32 %a, i32 %b) #0 {
404402

405403
define i32 @rev_or_rhs_rev32(i32 %a, i32 %b) #0 {
406404
; CHECK-LABEL: @rev_or_rhs_rev32(
407-
; CHECK-NEXT: [[TMP1:%.*]] = tail call i32 @llvm.bitreverse.i32(i32 [[B:%.*]])
408-
; CHECK-NEXT: [[TMP2:%.*]] = or i32 [[TMP1]], [[A:%.*]]
409-
; CHECK-NEXT: [[TMP3:%.*]] = tail call i32 @llvm.bitreverse.i32(i32 [[TMP2]])
410-
; CHECK-NEXT: ret i32 [[TMP3]]
405+
; CHECK-NEXT: [[TMP1:%.*]] = call i32 @llvm.bitreverse.i32(i32 [[A:%.*]])
406+
; CHECK-NEXT: [[TMP2:%.*]] = or i32 [[TMP1]], [[B:%.*]]
407+
; CHECK-NEXT: ret i32 [[TMP2]]
411408
;
412409
%1 = tail call i32 @llvm.bitreverse.i32(i32 %b)
413410
%2 = or i32 %a, %1
@@ -417,10 +414,9 @@ define i32 @rev_or_rhs_rev32(i32 %a, i32 %b) #0 {
417414

418415
define i64 @rev_or_rhs_rev64(i64 %a, i64 %b) #0 {
419416
; CHECK-LABEL: @rev_or_rhs_rev64(
420-
; CHECK-NEXT: [[TMP1:%.*]] = tail call i64 @llvm.bitreverse.i64(i64 [[B:%.*]])
421-
; CHECK-NEXT: [[TMP2:%.*]] = or i64 [[TMP1]], [[A:%.*]]
422-
; CHECK-NEXT: [[TMP3:%.*]] = tail call i64 @llvm.bitreverse.i64(i64 [[TMP2]])
423-
; CHECK-NEXT: ret i64 [[TMP3]]
417+
; CHECK-NEXT: [[TMP1:%.*]] = call i64 @llvm.bitreverse.i64(i64 [[A:%.*]])
418+
; CHECK-NEXT: [[TMP2:%.*]] = or i64 [[TMP1]], [[B:%.*]]
419+
; CHECK-NEXT: ret i64 [[TMP2]]
424420
;
425421
%1 = tail call i64 @llvm.bitreverse.i64(i64 %b)
426422
%2 = or i64 %a, %1
@@ -430,10 +426,9 @@ define i64 @rev_or_rhs_rev64(i64 %a, i64 %b) #0 {
430426

431427
define i64 @rev_xor_rhs_rev64(i64 %a, i64 %b) #0 {
432428
; CHECK-LABEL: @rev_xor_rhs_rev64(
433-
; CHECK-NEXT: [[TMP1:%.*]] = tail call i64 @llvm.bitreverse.i64(i64 [[B:%.*]])
434-
; CHECK-NEXT: [[TMP2:%.*]] = xor i64 [[TMP1]], [[A:%.*]]
435-
; CHECK-NEXT: [[TMP3:%.*]] = tail call i64 @llvm.bitreverse.i64(i64 [[TMP2]])
436-
; CHECK-NEXT: ret i64 [[TMP3]]
429+
; CHECK-NEXT: [[TMP1:%.*]] = call i64 @llvm.bitreverse.i64(i64 [[A:%.*]])
430+
; CHECK-NEXT: [[TMP2:%.*]] = xor i64 [[TMP1]], [[B:%.*]]
431+
; CHECK-NEXT: ret i64 [[TMP2]]
437432
;
438433
%1 = tail call i64 @llvm.bitreverse.i64(i64 %b)
439434
%2 = xor i64 %a, %1
@@ -443,10 +438,9 @@ define i64 @rev_xor_rhs_rev64(i64 %a, i64 %b) #0 {
443438

444439
define <2 x i32> @rev_xor_rhs_i32vec(<2 x i32> %a, <2 x i32> %b) #0 {
445440
; CHECK-LABEL: @rev_xor_rhs_i32vec(
446-
; CHECK-NEXT: [[TMP1:%.*]] = tail call <2 x i32> @llvm.bitreverse.v2i32(<2 x i32> [[B:%.*]])
447-
; CHECK-NEXT: [[TMP2:%.*]] = xor <2 x i32> [[TMP1]], [[A:%.*]]
448-
; CHECK-NEXT: [[TMP3:%.*]] = tail call <2 x i32> @llvm.bitreverse.v2i32(<2 x i32> [[TMP2]])
449-
; CHECK-NEXT: ret <2 x i32> [[TMP3]]
441+
; CHECK-NEXT: [[TMP1:%.*]] = call <2 x i32> @llvm.bitreverse.v2i32(<2 x i32> [[A:%.*]])
442+
; CHECK-NEXT: [[TMP2:%.*]] = xor <2 x i32> [[TMP1]], [[B:%.*]]
443+
; CHECK-NEXT: ret <2 x i32> [[TMP2]]
450444
;
451445
%1 = tail call <2 x i32> @llvm.bitreverse.v2i32(<2 x i32> %b)
452446
%2 = xor <2 x i32> %a, %1
@@ -486,11 +480,8 @@ define i64 @rev_and_rhs_rev64_multiuse2(i64 %a, i64 %b) #0 {
486480

487481
define i64 @rev_all_operand64(i64 %a, i64 %b) #0 {
488482
; CHECK-LABEL: @rev_all_operand64(
489-
; CHECK-NEXT: [[TMP1:%.*]] = tail call i64 @llvm.bitreverse.i64(i64 [[A:%.*]])
490-
; CHECK-NEXT: [[TMP2:%.*]] = tail call i64 @llvm.bitreverse.i64(i64 [[B:%.*]])
491-
; CHECK-NEXT: [[TMP3:%.*]] = and i64 [[TMP1]], [[TMP2]]
492-
; CHECK-NEXT: [[TMP4:%.*]] = tail call i64 @llvm.bitreverse.i64(i64 [[TMP3]])
493-
; CHECK-NEXT: ret i64 [[TMP4]]
483+
; CHECK-NEXT: [[TMP1:%.*]] = and i64 [[A:%.*]], [[B:%.*]]
484+
; CHECK-NEXT: ret i64 [[TMP1]]
494485
;
495486
%1 = tail call i64 @llvm.bitreverse.i64(i64 %a)
496487
%2 = tail call i64 @llvm.bitreverse.i64(i64 %b)
@@ -503,11 +494,10 @@ define i64 @rev_all_operand64_multiuse_both(i64 %a, i64 %b) #0 {
503494
; CHECK-LABEL: @rev_all_operand64_multiuse_both(
504495
; CHECK-NEXT: [[TMP1:%.*]] = tail call i64 @llvm.bitreverse.i64(i64 [[A:%.*]])
505496
; CHECK-NEXT: [[TMP2:%.*]] = tail call i64 @llvm.bitreverse.i64(i64 [[B:%.*]])
506-
; CHECK-NEXT: [[TMP3:%.*]] = and i64 [[TMP1]], [[TMP2]]
507-
; CHECK-NEXT: [[TMP4:%.*]] = tail call i64 @llvm.bitreverse.i64(i64 [[TMP3]])
497+
; CHECK-NEXT: [[TMP3:%.*]] = and i64 [[A]], [[B]]
508498
; CHECK-NEXT: call void @use_i64(i64 [[TMP1]])
509499
; CHECK-NEXT: call void @use_i64(i64 [[TMP2]])
510-
; CHECK-NEXT: ret i64 [[TMP4]]
500+
; CHECK-NEXT: ret i64 [[TMP3]]
511501
;
512502
%1 = tail call i64 @llvm.bitreverse.i64(i64 %a)
513503
%2 = tail call i64 @llvm.bitreverse.i64(i64 %b)

0 commit comments

Comments
 (0)