Skip to content

Commit c283dab

Browse files
committed
[InstCombine] 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 803e4e0 commit c283dab

File tree

2 files changed

+7
-4
lines changed

2 files changed

+7
-4
lines changed

llvm/lib/Transforms/InstCombine/InstCombineAndOrXor.cpp

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1869,6 +1869,9 @@ Instruction *InstCombinerImpl::foldCastedBitwiseLogic(BinaryOperator &I) {
18691869

18701870
// Do the logic op in the intermediate width, then widen more.
18711871
Value *NarrowLogic = Builder.CreateBinOp(LogicOpc, X, Y, I.getName());
1872+
if (auto *Disjoint = dyn_cast<PossiblyDisjointInst>(&I);
1873+
Disjoint && Disjoint->isDisjoint())
1874+
cast<PossiblyDisjointInst>(NarrowLogic)->setIsDisjoint(true);
18721875
return CastInst::Create(CastOpcode, NarrowLogic, DestTy);
18731876
}
18741877

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

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -4338,7 +4338,7 @@ define i16 @or_disjoint_zext_zext(i8 %x, i4 %y) {
43384338
; CHECK-LABEL: define {{[^@]+}}@or_disjoint_zext_zext
43394339
; CHECK-SAME: (i8 [[X:%.*]], i4 [[Y:%.*]]) {
43404340
; CHECK-NEXT: [[TMP1:%.*]] = zext i4 [[Y]] to i8
4341-
; CHECK-NEXT: [[R1:%.*]] = or i8 [[X]], [[TMP1]]
4341+
; CHECK-NEXT: [[R1:%.*]] = or disjoint i8 [[X]], [[TMP1]]
43424342
; CHECK-NEXT: [[R:%.*]] = zext i8 [[R1]] to i16
43434343
; CHECK-NEXT: ret i16 [[R]]
43444344
;
@@ -4351,7 +4351,7 @@ define i16 @or_disjoint_zext_zext(i8 %x, i4 %y) {
43514351
define i16 @or_disjoint_zext_zext_2(i8 %x, i8 %y) {
43524352
; CHECK-LABEL: define {{[^@]+}}@or_disjoint_zext_zext_2
43534353
; CHECK-SAME: (i8 [[X:%.*]], i8 [[Y:%.*]]) {
4354-
; CHECK-NEXT: [[R1:%.*]] = or i8 [[Y]], [[X]]
4354+
; CHECK-NEXT: [[R1:%.*]] = or disjoint i8 [[Y]], [[X]]
43554355
; CHECK-NEXT: [[R:%.*]] = zext i8 [[R1]] to i16
43564356
; CHECK-NEXT: ret i16 [[R]]
43574357
;
@@ -4494,7 +4494,7 @@ define i16 @or_disjoint_sext_sext(i8 %x, i4 %y) {
44944494
; CHECK-LABEL: define {{[^@]+}}@or_disjoint_sext_sext
44954495
; CHECK-SAME: (i8 [[X:%.*]], i4 [[Y:%.*]]) {
44964496
; CHECK-NEXT: [[TMP1:%.*]] = sext i4 [[Y]] to i8
4497-
; CHECK-NEXT: [[R1:%.*]] = or i8 [[X]], [[TMP1]]
4497+
; CHECK-NEXT: [[R1:%.*]] = or disjoint i8 [[X]], [[TMP1]]
44984498
; CHECK-NEXT: [[R:%.*]] = sext i8 [[R1]] to i16
44994499
; CHECK-NEXT: ret i16 [[R]]
45004500
;
@@ -4507,7 +4507,7 @@ define i16 @or_disjoint_sext_sext(i8 %x, i4 %y) {
45074507
define i16 @or_disjoint_sext_sext_2(i8 %x, i8 %y) {
45084508
; CHECK-LABEL: define {{[^@]+}}@or_disjoint_sext_sext_2
45094509
; CHECK-SAME: (i8 [[X:%.*]], i8 [[Y:%.*]]) {
4510-
; CHECK-NEXT: [[R1:%.*]] = or i8 [[X]], [[Y]]
4510+
; CHECK-NEXT: [[R1:%.*]] = or disjoint i8 [[X]], [[Y]]
45114511
; CHECK-NEXT: [[R:%.*]] = sext i8 [[R1]] to i16
45124512
; CHECK-NEXT: ret i16 [[R]]
45134513
;

0 commit comments

Comments
 (0)