Skip to content

Commit f9ad634

Browse files
committed
[RISCV] Keep or disjoint after folding casted bitwise logic
Optimize `or disjoint (zext/sext a) (zext/sext b))` to `(zext/sext (or disjoint a, b))` without losing disjoint. Confirmed by: https://alive2.llvm.org/ce/z/kQ5fJv.
1 parent 7637bde commit f9ad634

File tree

2 files changed

+23
-21
lines changed

2 files changed

+23
-21
lines changed

llvm/lib/Transforms/InstCombine/InstCombineAndOrXor.cpp

Lines changed: 21 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -1846,27 +1846,29 @@ Instruction *InstCombinerImpl::foldCastedBitwiseLogic(BinaryOperator &I) {
18461846
if (CastOpcode != Cast1->getOpcode())
18471847
return nullptr;
18481848

1849-
// If the source types do not match, but the casts are matching extends, we
1850-
// can still narrow the logic op.
1851-
if (SrcTy != Cast1->getSrcTy()) {
1852-
Value *X, *Y;
1853-
if (match(Cast0, m_OneUse(m_ZExtOrSExt(m_Value(X)))) &&
1854-
match(Cast1, m_OneUse(m_ZExtOrSExt(m_Value(Y))))) {
1855-
// Cast the narrower source to the wider source type.
1856-
unsigned XNumBits = X->getType()->getScalarSizeInBits();
1857-
unsigned YNumBits = Y->getType()->getScalarSizeInBits();
1858-
if (XNumBits < YNumBits)
1859-
X = Builder.CreateCast(CastOpcode, X, Y->getType());
1860-
else
1861-
Y = Builder.CreateCast(CastOpcode, Y, X->getType());
1862-
// Do the logic op in the intermediate width, then widen more.
1863-
Value *NarrowLogic = Builder.CreateBinOp(LogicOpc, X, Y);
1864-
return CastInst::Create(CastOpcode, NarrowLogic, DestTy);
1865-
}
1849+
Value *X, *Y;
1850+
if (match(Cast0, m_OneUse(m_ZExtOrSExt(m_Value(X)))) &&
1851+
match(Cast1, m_OneUse(m_ZExtOrSExt(m_Value(Y))))) {
1852+
// Cast the narrower source to the wider source type.
1853+
unsigned XNumBits = X->getType()->getScalarSizeInBits();
1854+
unsigned YNumBits = Y->getType()->getScalarSizeInBits();
1855+
// If the source types do not match, but the casts are matching extends, we
1856+
// can still narrow the logic op.
1857+
if (XNumBits < YNumBits)
1858+
X = Builder.CreateCast(CastOpcode, X, Y->getType());
1859+
else if (YNumBits < XNumBits)
1860+
Y = Builder.CreateCast(CastOpcode, Y, X->getType());
1861+
1862+
// Do the logic op in the intermediate width, then widen more.
1863+
Value *NarrowLogic = Builder.CreateBinOp(LogicOpc, X, Y);
1864+
if (auto *Disjoint = dyn_cast<PossiblyDisjointInst>(&I);
1865+
Disjoint && Disjoint->isDisjoint())
1866+
cast<PossiblyDisjointInst>(NarrowLogic)->setIsDisjoint(true);
1867+
return CastInst::Create(CastOpcode, NarrowLogic, DestTy);
1868+
}
18661869

1867-
// Give up for other cast opcodes.
1870+
if (SrcTy != Cast1->getSrcTy())
18681871
return nullptr;
1869-
}
18701872

18711873
Value *Cast0Src = Cast0->getOperand(0);
18721874
Value *Cast1Src = Cast1->getOperand(0);

llvm/test/Transforms/InstCombine/and-xor-or.ll

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4278,7 +4278,7 @@ define i16 @or_disjoint_zext_zext(i8 %x, i4 %y) {
42784278
; CHECK-LABEL: define {{[^@]+}}@or_disjoint_zext_zext
42794279
; CHECK-SAME: (i8 [[X:%.*]], i4 [[Y:%.*]]) {
42804280
; CHECK-NEXT: [[TMP1:%.*]] = zext i4 [[Y]] to i8
4281-
; CHECK-NEXT: [[TMP2:%.*]] = or i8 [[X]], [[TMP1]]
4281+
; CHECK-NEXT: [[TMP2:%.*]] = or disjoint i8 [[X]], [[TMP1]]
42824282
; CHECK-NEXT: [[R:%.*]] = zext i8 [[TMP2]] to i16
42834283
; CHECK-NEXT: ret i16 [[R]]
42844284
;
@@ -4334,7 +4334,7 @@ define i16 @or_disjoint_sext_sext(i8 %x, i4 %y) {
43344334
; CHECK-LABEL: define {{[^@]+}}@or_disjoint_sext_sext
43354335
; CHECK-SAME: (i8 [[X:%.*]], i4 [[Y:%.*]]) {
43364336
; CHECK-NEXT: [[TMP1:%.*]] = sext i4 [[Y]] to i8
4337-
; CHECK-NEXT: [[TMP2:%.*]] = or i8 [[X]], [[TMP1]]
4337+
; CHECK-NEXT: [[TMP2:%.*]] = or disjoint i8 [[X]], [[TMP1]]
43384338
; CHECK-NEXT: [[R:%.*]] = sext i8 [[TMP2]] to i16
43394339
; CHECK-NEXT: ret i16 [[R]]
43404340
;

0 commit comments

Comments
 (0)