Skip to content

Commit 64bba21

Browse files
authored
[InstCombine] Propagate disjoint flags during shl-binop transform (llvm#91333)
Alive2 Proof: https://alive2.llvm.org/ce/z/D2jHrn
1 parent 6e14583 commit 64bba21

File tree

2 files changed

+40
-3
lines changed

2 files changed

+40
-3
lines changed

llvm/lib/Transforms/InstCombine/InstCombineShifts.cpp

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1174,7 +1174,11 @@ Instruction *InstCombinerImpl::visitShl(BinaryOperator &I) {
11741174
// X & (CC << C)
11751175
Value *M = Builder.CreateAnd(X, ConstantInt::get(Ty, CC->shl(*C)),
11761176
X->getName() + ".mask");
1177-
return BinaryOperator::Create(Op0BO->getOpcode(), M, YS);
1177+
auto *NewOp = BinaryOperator::Create(Op0BO->getOpcode(), M, YS);
1178+
if (auto *Disjoint = dyn_cast<PossiblyDisjointInst>(Op0BO);
1179+
Disjoint && Disjoint->isDisjoint())
1180+
cast<PossiblyDisjointInst>(NewOp)->setIsDisjoint(true);
1181+
return NewOp;
11781182
}
11791183
}
11801184

llvm/test/Transforms/InstCombine/shl-bo.ll

Lines changed: 35 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -294,6 +294,39 @@ define i8 @lshr_and_or(i8 %a, i8 %y) {
294294
ret i8 %l
295295
}
296296

297+
define i8 @lshr_and_or_disjoint(i8 %a, i8 %y) {
298+
; CHECK-LABEL: @lshr_and_or_disjoint(
299+
; CHECK-NEXT: [[X:%.*]] = srem i8 [[A:%.*]], 42
300+
; CHECK-NEXT: [[B1:%.*]] = shl i8 [[X]], 2
301+
; CHECK-NEXT: [[Y_MASK:%.*]] = and i8 [[Y:%.*]], 52
302+
; CHECK-NEXT: [[L:%.*]] = or disjoint i8 [[Y_MASK]], [[B1]]
303+
; CHECK-NEXT: ret i8 [[L]]
304+
;
305+
%x = srem i8 %a, 42 ; thwart complexity-based canonicalization
306+
%r = lshr i8 %y, 2
307+
%m = and i8 %r, 13
308+
%b = or disjoint i8 %x, %m
309+
%l = shl i8 %b, 2
310+
ret i8 %l
311+
}
312+
313+
define i8 @ashr_and_or_disjoint(i8 %a, i8 %y) {
314+
; CHECK-LABEL: @ashr_and_or_disjoint(
315+
; CHECK-NEXT: [[X:%.*]] = srem i8 [[A:%.*]], 42
316+
; CHECK-NEXT: [[B1:%.*]] = shl i8 [[X]], 2
317+
; CHECK-NEXT: [[Y_MASK:%.*]] = and i8 [[Y:%.*]], 52
318+
; CHECK-NEXT: [[L:%.*]] = or disjoint i8 [[Y_MASK]], [[B1]]
319+
; CHECK-NEXT: ret i8 [[L]]
320+
;
321+
%x = srem i8 %a, 42 ; thwart complexity-based canonicalization
322+
%r = ashr i8 %y, 2
323+
%m = and i8 %r, 13
324+
%b = or disjoint i8 %x, %m
325+
%l = shl i8 %b, 2
326+
ret i8 %l
327+
}
328+
329+
297330
define <2 x i8> @lshr_and_or_commute_splat(<2 x i8> %a, <2 x i8> %y) {
298331
; CHECK-LABEL: @lshr_and_or_commute_splat(
299332
; CHECK-NEXT: [[X:%.*]] = srem <2 x i8> [[A:%.*]], <i8 42, i8 42>
@@ -614,8 +647,8 @@ define <8 x i16> @test_FoldShiftByConstant_CreateSHL2(<8 x i16> %in) {
614647

615648
define <16 x i8> @test_FoldShiftByConstant_CreateAnd(<16 x i8> %in0) {
616649
; CHECK-LABEL: @test_FoldShiftByConstant_CreateAnd(
617-
; CHECK-NEXT: [[TMP1:%.*]] = mul <16 x i8> [[IN0:%.*]], <i8 33, i8 33, i8 33, i8 33, i8 33, i8 33, i8 33, i8 33, i8 33, i8 33, i8 33, i8 33, i8 33, i8 33, i8 33, i8 33>
618-
; CHECK-NEXT: [[VSHL_N:%.*]] = and <16 x i8> [[TMP1]], <i8 -32, i8 -32, i8 -32, i8 -32, i8 -32, i8 -32, i8 -32, i8 -32, i8 -32, i8 -32, i8 -32, i8 -32, i8 -32, i8 -32, i8 -32, i8 -32>
650+
; CHECK-NEXT: [[VSRA_N2:%.*]] = mul <16 x i8> [[IN0:%.*]], <i8 33, i8 33, i8 33, i8 33, i8 33, i8 33, i8 33, i8 33, i8 33, i8 33, i8 33, i8 33, i8 33, i8 33, i8 33, i8 33>
651+
; CHECK-NEXT: [[VSHL_N:%.*]] = and <16 x i8> [[VSRA_N2]], <i8 -32, i8 -32, i8 -32, i8 -32, i8 -32, i8 -32, i8 -32, i8 -32, i8 -32, i8 -32, i8 -32, i8 -32, i8 -32, i8 -32, i8 -32, i8 -32>
619652
; CHECK-NEXT: ret <16 x i8> [[VSHL_N]]
620653
;
621654
%vsra_n = ashr <16 x i8> %in0, <i8 5, i8 5, i8 5, i8 5, i8 5, i8 5, i8 5, i8 5, i8 5, i8 5, i8 5, i8 5, i8 5, i8 5, i8 5, i8 5>

0 commit comments

Comments
 (0)