Skip to content

Commit 2dd52b4

Browse files
committed
[InstCombine] Improve logic for adding flags to shift instructions.
Instead of relying on constant operands, use known bits to do the computation. Proofs: https://alive2.llvm.org/ce/z/M-aBnw Differential Revision: https://reviews.llvm.org/D157532
1 parent 968468a commit 2dd52b4

File tree

8 files changed

+95
-58
lines changed

8 files changed

+95
-58
lines changed

llvm/lib/Transforms/InstCombine/InstCombineShifts.cpp

Lines changed: 65 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -941,6 +941,60 @@ Instruction *InstCombinerImpl::foldLShrOverflowBit(BinaryOperator &I) {
941941
return new ZExtInst(Overflow, Ty);
942942
}
943943

944+
// Try to set nuw/nsw flags on shl or exact flag on lshr/ashr using knownbits.
945+
static bool setShiftFlags(BinaryOperator &I, const SimplifyQuery &Q) {
946+
assert(I.isShift() && "Expected a shift as input");
947+
// We already have all the flags.
948+
if (I.getOpcode() == Instruction::Shl) {
949+
if (I.hasNoUnsignedWrap() && I.hasNoSignedWrap())
950+
return false;
951+
} else {
952+
if (I.isExact())
953+
return false;
954+
}
955+
956+
// Compute what we know about shift count.
957+
KnownBits KnownCnt =
958+
computeKnownBits(I.getOperand(1), Q.DL, /*Depth*/ 0, Q.AC, Q.CxtI, Q.DT);
959+
// If we know nothing about shift count or its a poison shift, we won't be
960+
// able to prove anything so return before computing shift amount.
961+
if (KnownCnt.isUnknown())
962+
return false;
963+
unsigned BitWidth = KnownCnt.getBitWidth();
964+
APInt MaxCnt = KnownCnt.getMaxValue();
965+
if (MaxCnt.uge(BitWidth))
966+
return false;
967+
968+
KnownBits KnownAmt =
969+
computeKnownBits(I.getOperand(0), Q.DL, /*Depth*/ 0, Q.AC, Q.CxtI, Q.DT);
970+
bool Changed = false;
971+
972+
if (I.getOpcode() == Instruction::Shl) {
973+
// If we have as many leading zeros than maximum shift cnt we have nuw.
974+
if (!I.hasNoUnsignedWrap() && MaxCnt.ule(KnownAmt.countMinLeadingZeros())) {
975+
I.setHasNoUnsignedWrap();
976+
Changed = true;
977+
}
978+
// If we have more sign bits than maximum shift cnt we have nsw.
979+
if (!I.hasNoSignedWrap()) {
980+
if (MaxCnt.ult(KnownAmt.countMinSignBits()) ||
981+
MaxCnt.ult(ComputeNumSignBits(I.getOperand(0), Q.DL, /*Depth*/ 0,
982+
Q.AC, Q.CxtI, Q.DT))) {
983+
I.setHasNoSignedWrap();
984+
Changed = true;
985+
}
986+
}
987+
return Changed;
988+
}
989+
990+
// If we have at least as many trailing zeros as maximum count then we have
991+
// exact.
992+
Changed = MaxCnt.ule(KnownAmt.countMinTrailingZeros());
993+
I.setIsExact(Changed);
994+
995+
return Changed;
996+
}
997+
944998
Instruction *InstCombinerImpl::visitShl(BinaryOperator &I) {
945999
const SimplifyQuery Q = SQ.getWithInstruction(&I);
9461000

@@ -1121,22 +1175,11 @@ Instruction *InstCombinerImpl::visitShl(BinaryOperator &I) {
11211175
Value *NewShift = Builder.CreateShl(X, Op1);
11221176
return BinaryOperator::CreateSub(NewLHS, NewShift);
11231177
}
1124-
1125-
// If the shifted-out value is known-zero, then this is a NUW shift.
1126-
if (!I.hasNoUnsignedWrap() &&
1127-
MaskedValueIsZero(Op0, APInt::getHighBitsSet(BitWidth, ShAmtC), 0,
1128-
&I)) {
1129-
I.setHasNoUnsignedWrap();
1130-
return &I;
1131-
}
1132-
1133-
// If the shifted-out value is all signbits, then this is a NSW shift.
1134-
if (!I.hasNoSignedWrap() && ComputeNumSignBits(Op0, 0, &I) > ShAmtC) {
1135-
I.setHasNoSignedWrap();
1136-
return &I;
1137-
}
11381178
}
11391179

1180+
if (setShiftFlags(I, Q))
1181+
return &I;
1182+
11401183
// Transform (x >> y) << y to x & (-1 << y)
11411184
// Valid for any type of right-shift.
11421185
Value *X;
@@ -1427,15 +1470,12 @@ Instruction *InstCombinerImpl::visitLShr(BinaryOperator &I) {
14271470
Value *And = Builder.CreateAnd(BoolX, BoolY);
14281471
return new ZExtInst(And, Ty);
14291472
}
1430-
1431-
// If the shifted-out value is known-zero, then this is an exact shift.
1432-
if (!I.isExact() &&
1433-
MaskedValueIsZero(Op0, APInt::getLowBitsSet(BitWidth, ShAmtC), 0, &I)) {
1434-
I.setIsExact();
1435-
return &I;
1436-
}
14371473
}
14381474

1475+
const SimplifyQuery Q = SQ.getWithInstruction(&I);
1476+
if (setShiftFlags(I, Q))
1477+
return &I;
1478+
14391479
// Transform (x << y) >> y to x & (-1 >> y)
14401480
if (match(Op0, m_OneUse(m_Shl(m_Value(X), m_Specific(Op1))))) {
14411481
Constant *AllOnes = ConstantInt::getAllOnesValue(Ty);
@@ -1594,15 +1634,12 @@ Instruction *InstCombinerImpl::visitAShr(BinaryOperator &I) {
15941634
if (match(Op0, m_OneUse(m_NSWSub(m_Value(X), m_Value(Y)))))
15951635
return new SExtInst(Builder.CreateICmpSLT(X, Y), Ty);
15961636
}
1597-
1598-
// If the shifted-out value is known-zero, then this is an exact shift.
1599-
if (!I.isExact() &&
1600-
MaskedValueIsZero(Op0, APInt::getLowBitsSet(BitWidth, ShAmt), 0, &I)) {
1601-
I.setIsExact();
1602-
return &I;
1603-
}
16041637
}
16051638

1639+
const SimplifyQuery Q = SQ.getWithInstruction(&I);
1640+
if (setShiftFlags(I, Q))
1641+
return &I;
1642+
16061643
// Prefer `-(x & 1)` over `(x << (bitwidth(x)-1)) a>> (bitwidth(x)-1)`
16071644
// as the pattern to splat the lowest bit.
16081645
// FIXME: iff X is already masked, we don't need the one-use check.

llvm/test/Analysis/ValueTracking/known-power-of-two.ll

Lines changed: 15 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -413,11 +413,11 @@ define i1 @mul_is_pow2(i16 %x, i16 %y, i16 %z) {
413413
; CHECK-SAME: (i16 [[X:%.*]], i16 [[Y:%.*]], i16 [[Z:%.*]]) {
414414
; CHECK-NEXT: [[XSMALL:%.*]] = and i16 [[X]], 3
415415
; CHECK-NEXT: [[ZSMALL:%.*]] = and i16 [[Z]], 3
416-
; CHECK-NEXT: [[XP2:%.*]] = shl i16 4, [[XSMALL]]
417-
; CHECK-NEXT: [[ZP2:%.*]] = shl i16 2, [[ZSMALL]]
418-
; CHECK-NEXT: [[XX:%.*]] = mul nuw nsw i16 [[XP2]], [[ZP2]]
416+
; CHECK-NEXT: [[ZP2:%.*]] = shl nuw nsw i16 2, [[ZSMALL]]
417+
; CHECK-NEXT: [[TMP1:%.*]] = add nuw nsw i16 [[XSMALL]], 2
418+
; CHECK-NEXT: [[XX:%.*]] = shl nuw nsw i16 [[ZP2]], [[TMP1]]
419419
; CHECK-NEXT: [[AND:%.*]] = and i16 [[XX]], [[Y]]
420-
; CHECK-NEXT: [[R:%.*]] = icmp eq i16 [[AND]], [[XX]]
420+
; CHECK-NEXT: [[R:%.*]] = icmp ne i16 [[AND]], 0
421421
; CHECK-NEXT: ret i1 [[R]]
422422
;
423423
%xsmall = and i16 %x, 3
@@ -436,9 +436,9 @@ define i1 @mul_is_pow2_fail(i16 %x, i16 %y, i16 %z) {
436436
; CHECK-SAME: (i16 [[X:%.*]], i16 [[Y:%.*]], i16 [[Z:%.*]]) {
437437
; CHECK-NEXT: [[XSMALL:%.*]] = and i16 [[X]], 7
438438
; CHECK-NEXT: [[ZSMALL:%.*]] = and i16 [[Z]], 7
439-
; CHECK-NEXT: [[XP2:%.*]] = shl i16 4, [[XSMALL]]
440-
; CHECK-NEXT: [[ZP2:%.*]] = shl i16 2, [[ZSMALL]]
441-
; CHECK-NEXT: [[XX:%.*]] = mul i16 [[XP2]], [[ZP2]]
439+
; CHECK-NEXT: [[ZP2:%.*]] = shl nuw nsw i16 2, [[ZSMALL]]
440+
; CHECK-NEXT: [[TMP1:%.*]] = add nuw nsw i16 [[XSMALL]], 2
441+
; CHECK-NEXT: [[XX:%.*]] = shl i16 [[ZP2]], [[TMP1]]
442442
; CHECK-NEXT: [[AND:%.*]] = and i16 [[XX]], [[Y]]
443443
; CHECK-NEXT: [[R:%.*]] = icmp eq i16 [[AND]], [[XX]]
444444
; CHECK-NEXT: ret i1 [[R]]
@@ -459,9 +459,9 @@ define i1 @mul_is_pow2_fail2(i16 %x, i16 %y, i16 %z) {
459459
; CHECK-SAME: (i16 [[X:%.*]], i16 [[Y:%.*]], i16 [[Z:%.*]]) {
460460
; CHECK-NEXT: [[XSMALL:%.*]] = and i16 [[X]], 3
461461
; CHECK-NEXT: [[ZSMALL:%.*]] = and i16 [[Z]], 3
462-
; CHECK-NEXT: [[XP2:%.*]] = shl i16 3, [[XSMALL]]
463-
; CHECK-NEXT: [[ZP2:%.*]] = shl i16 2, [[ZSMALL]]
464-
; CHECK-NEXT: [[XX:%.*]] = mul nuw nsw i16 [[XP2]], [[ZP2]]
462+
; CHECK-NEXT: [[XP2:%.*]] = shl nuw nsw i16 3, [[XSMALL]]
463+
; CHECK-NEXT: [[TMP1:%.*]] = add nuw nsw i16 [[ZSMALL]], 1
464+
; CHECK-NEXT: [[XX:%.*]] = shl nuw nsw i16 [[XP2]], [[TMP1]]
465465
; CHECK-NEXT: [[AND:%.*]] = and i16 [[XX]], [[Y]]
466466
; CHECK-NEXT: [[R:%.*]] = icmp eq i16 [[AND]], [[XX]]
467467
; CHECK-NEXT: ret i1 [[R]]
@@ -481,9 +481,9 @@ define i1 @shl_is_pow2(i16 %x, i16 %y) {
481481
; CHECK-LABEL: define i1 @shl_is_pow2
482482
; CHECK-SAME: (i16 [[X:%.*]], i16 [[Y:%.*]]) {
483483
; CHECK-NEXT: [[XSMALL:%.*]] = and i16 [[X]], 7
484-
; CHECK-NEXT: [[XX:%.*]] = shl i16 4, [[XSMALL]]
484+
; CHECK-NEXT: [[XX:%.*]] = shl nuw nsw i16 4, [[XSMALL]]
485485
; CHECK-NEXT: [[AND:%.*]] = and i16 [[XX]], [[Y]]
486-
; CHECK-NEXT: [[R:%.*]] = icmp eq i16 [[AND]], [[XX]]
486+
; CHECK-NEXT: [[R:%.*]] = icmp ne i16 [[AND]], 0
487487
; CHECK-NEXT: ret i1 [[R]]
488488
;
489489
%xsmall = and i16 %x, 7
@@ -515,7 +515,7 @@ define i1 @shl_is_pow2_fail2(i16 %x, i16 %y) {
515515
; CHECK-LABEL: define i1 @shl_is_pow2_fail2
516516
; CHECK-SAME: (i16 [[X:%.*]], i16 [[Y:%.*]]) {
517517
; CHECK-NEXT: [[XSMALL:%.*]] = and i16 [[X]], 7
518-
; CHECK-NEXT: [[XX:%.*]] = shl i16 5, [[XSMALL]]
518+
; CHECK-NEXT: [[XX:%.*]] = shl nuw nsw i16 5, [[XSMALL]]
519519
; CHECK-NEXT: [[AND:%.*]] = and i16 [[XX]], [[Y]]
520520
; CHECK-NEXT: [[R:%.*]] = icmp eq i16 [[AND]], [[XX]]
521521
; CHECK-NEXT: ret i1 [[R]]
@@ -532,9 +532,9 @@ define i1 @lshr_is_pow2(i16 %x, i16 %y) {
532532
; CHECK-LABEL: define i1 @lshr_is_pow2
533533
; CHECK-SAME: (i16 [[X:%.*]], i16 [[Y:%.*]]) {
534534
; CHECK-NEXT: [[XSMALL:%.*]] = and i16 [[X]], 7
535-
; CHECK-NEXT: [[XX:%.*]] = lshr i16 512, [[XSMALL]]
535+
; CHECK-NEXT: [[XX:%.*]] = lshr exact i16 512, [[XSMALL]]
536536
; CHECK-NEXT: [[AND:%.*]] = and i16 [[XX]], [[Y]]
537-
; CHECK-NEXT: [[R:%.*]] = icmp eq i16 [[AND]], [[XX]]
537+
; CHECK-NEXT: [[R:%.*]] = icmp ne i16 [[AND]], 0
538538
; CHECK-NEXT: ret i1 [[R]]
539539
;
540540
%xsmall = and i16 %x, 7

llvm/test/Transforms/InstCombine/and-add-shl.ll

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@ define i8 @and_not_shl(i8 %x) {
2929
; CHECK-SAME: (i8 [[X:%.*]]) {
3030
; CHECK-NEXT: [[OP1_P2:%.*]] = icmp ult i8 [[X]], 6
3131
; CHECK-NEXT: call void @llvm.assume(i1 [[OP1_P2]])
32-
; CHECK-NEXT: [[SHIFT:%.*]] = shl i8 -1, [[X]]
32+
; CHECK-NEXT: [[SHIFT:%.*]] = shl nsw i8 -1, [[X]]
3333
; CHECK-NEXT: [[NOT:%.*]] = and i8 [[SHIFT]], 32
3434
; CHECK-NEXT: [[R:%.*]] = xor i8 [[NOT]], 32
3535
; CHECK-NEXT: ret i8 [[R]]

llvm/test/Transforms/InstCombine/redundant-left-shift-input-masking-pr49778.ll

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,10 +5,10 @@
55
define i32 @src(i1 %x2) {
66
; CHECK-LABEL: @src(
77
; CHECK-NEXT: [[X13:%.*]] = zext i1 [[X2:%.*]] to i32
8-
; CHECK-NEXT: [[_7:%.*]] = shl i32 -1, [[X13]]
8+
; CHECK-NEXT: [[_7:%.*]] = shl nsw i32 -1, [[X13]]
99
; CHECK-NEXT: [[MASK:%.*]] = xor i32 [[_7]], -1
1010
; CHECK-NEXT: [[_8:%.*]] = and i32 [[MASK]], [[X13]]
11-
; CHECK-NEXT: [[_9:%.*]] = shl i32 [[_8]], [[X13]]
11+
; CHECK-NEXT: [[_9:%.*]] = shl nuw nsw i32 [[_8]], [[X13]]
1212
; CHECK-NEXT: ret i32 [[_9]]
1313
;
1414
%x13 = zext i1 %x2 to i32

llvm/test/Transforms/InstCombine/rotate.ll

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -705,7 +705,7 @@ define i9 @rotateleft_9_neg_mask_wide_amount_commute(i9 %v, i33 %shamt) {
705705
; CHECK-NEXT: [[LSHAMT:%.*]] = and i33 [[SHAMT]], 8
706706
; CHECK-NEXT: [[RSHAMT:%.*]] = and i33 [[NEG]], 8
707707
; CHECK-NEXT: [[CONV:%.*]] = zext i9 [[V:%.*]] to i33
708-
; CHECK-NEXT: [[SHL:%.*]] = shl i33 [[CONV]], [[LSHAMT]]
708+
; CHECK-NEXT: [[SHL:%.*]] = shl nuw nsw i33 [[CONV]], [[LSHAMT]]
709709
; CHECK-NEXT: [[SHR:%.*]] = lshr i33 [[CONV]], [[RSHAMT]]
710710
; CHECK-NEXT: [[OR:%.*]] = or i33 [[SHL]], [[SHR]]
711711
; CHECK-NEXT: [[RET:%.*]] = trunc i33 [[OR]] to i9

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

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ define i8 @shl_add_nuw(i8 %amt_in, i8 %cnt_in) {
55
; CHECK-LABEL: @shl_add_nuw(
66
; CHECK-NEXT: [[AMT:%.*]] = and i8 [[AMT_IN:%.*]], 63
77
; CHECK-NEXT: [[CNT:%.*]] = and i8 [[CNT_IN:%.*]], 2
8-
; CHECK-NEXT: [[R:%.*]] = shl i8 [[AMT]], [[CNT]]
8+
; CHECK-NEXT: [[R:%.*]] = shl nuw i8 [[AMT]], [[CNT]]
99
; CHECK-NEXT: ret i8 [[R]]
1010
;
1111
%amt = and i8 %amt_in, 63
@@ -31,7 +31,7 @@ define i8 @shl_add_nuw_and_nsw(i8 %amt_in, i8 %cnt_in) {
3131
; CHECK-LABEL: @shl_add_nuw_and_nsw(
3232
; CHECK-NEXT: [[AMT:%.*]] = and i8 [[AMT_IN:%.*]], 31
3333
; CHECK-NEXT: [[CNT:%.*]] = and i8 [[CNT_IN:%.*]], 2
34-
; CHECK-NEXT: [[R:%.*]] = shl i8 [[AMT]], [[CNT]]
34+
; CHECK-NEXT: [[R:%.*]] = shl nuw nsw i8 [[AMT]], [[CNT]]
3535
; CHECK-NEXT: ret i8 [[R]]
3636
;
3737
%amt = and i8 %amt_in, 31
@@ -44,7 +44,7 @@ define i8 @shl_add_nsw(i8 %amt_in, i8 %cnt_in) {
4444
; CHECK-LABEL: @shl_add_nsw(
4545
; CHECK-NEXT: [[AMT:%.*]] = or i8 [[AMT_IN:%.*]], -32
4646
; CHECK-NEXT: [[CNT:%.*]] = and i8 [[CNT_IN:%.*]], 2
47-
; CHECK-NEXT: [[R:%.*]] = shl i8 [[AMT]], [[CNT]]
47+
; CHECK-NEXT: [[R:%.*]] = shl nsw i8 [[AMT]], [[CNT]]
4848
; CHECK-NEXT: ret i8 [[R]]
4949
;
5050
%amt = or i8 %amt_in, 224
@@ -70,7 +70,7 @@ define i8 @lshr_add_exact(i8 %amt_in, i8 %cnt_in) {
7070
; CHECK-LABEL: @lshr_add_exact(
7171
; CHECK-NEXT: [[AMT:%.*]] = and i8 [[AMT_IN:%.*]], -4
7272
; CHECK-NEXT: [[CNT:%.*]] = and i8 [[CNT_IN:%.*]], 2
73-
; CHECK-NEXT: [[R:%.*]] = lshr i8 [[AMT]], [[CNT]]
73+
; CHECK-NEXT: [[R:%.*]] = lshr exact i8 [[AMT]], [[CNT]]
7474
; CHECK-NEXT: ret i8 [[R]]
7575
;
7676
%amt = and i8 %amt_in, -4
@@ -96,7 +96,7 @@ define i8 @ashr_add_exact(i8 %amt_in, i8 %cnt_in) {
9696
; CHECK-LABEL: @ashr_add_exact(
9797
; CHECK-NEXT: [[AMT:%.*]] = and i8 [[AMT_IN:%.*]], -14
9898
; CHECK-NEXT: [[CNT:%.*]] = and i8 [[CNT_IN:%.*]], 1
99-
; CHECK-NEXT: [[R:%.*]] = ashr i8 [[AMT]], [[CNT]]
99+
; CHECK-NEXT: [[R:%.*]] = ashr exact i8 [[AMT]], [[CNT]]
100100
; CHECK-NEXT: ret i8 [[R]]
101101
;
102102
%amt = and i8 %amt_in, -14

llvm/test/Transforms/InstCombine/trunc-inseltpoison.ll

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -345,7 +345,7 @@ define i64 @test11(i32 %A, i32 %B) {
345345
; CHECK-NEXT: [[C:%.*]] = zext i32 [[A:%.*]] to i64
346346
; CHECK-NEXT: [[TMP1:%.*]] = and i32 [[B:%.*]], 31
347347
; CHECK-NEXT: [[E:%.*]] = zext i32 [[TMP1]] to i64
348-
; CHECK-NEXT: [[F:%.*]] = shl i64 [[C]], [[E]]
348+
; CHECK-NEXT: [[F:%.*]] = shl nuw nsw i64 [[C]], [[E]]
349349
; CHECK-NEXT: ret i64 [[F]]
350350
;
351351
%C = zext i32 %A to i128
@@ -361,7 +361,7 @@ define <2 x i64> @test11_vec(<2 x i32> %A, <2 x i32> %B) {
361361
; CHECK-NEXT: [[C:%.*]] = zext <2 x i32> [[A:%.*]] to <2 x i64>
362362
; CHECK-NEXT: [[TMP1:%.*]] = and <2 x i32> [[B:%.*]], <i32 31, i32 31>
363363
; CHECK-NEXT: [[E:%.*]] = zext <2 x i32> [[TMP1]] to <2 x i64>
364-
; CHECK-NEXT: [[F:%.*]] = shl <2 x i64> [[C]], [[E]]
364+
; CHECK-NEXT: [[F:%.*]] = shl nuw nsw <2 x i64> [[C]], [[E]]
365365
; CHECK-NEXT: ret <2 x i64> [[F]]
366366
;
367367
%C = zext <2 x i32> %A to <2 x i128>
@@ -377,7 +377,7 @@ define <2 x i64> @test11_vec_nonuniform(<2 x i32> %A, <2 x i32> %B) {
377377
; CHECK-NEXT: [[C:%.*]] = zext <2 x i32> [[A:%.*]] to <2 x i64>
378378
; CHECK-NEXT: [[TMP1:%.*]] = and <2 x i32> [[B:%.*]], <i32 31, i32 15>
379379
; CHECK-NEXT: [[E:%.*]] = zext <2 x i32> [[TMP1]] to <2 x i64>
380-
; CHECK-NEXT: [[F:%.*]] = shl <2 x i64> [[C]], [[E]]
380+
; CHECK-NEXT: [[F:%.*]] = shl nuw nsw <2 x i64> [[C]], [[E]]
381381
; CHECK-NEXT: ret <2 x i64> [[F]]
382382
;
383383
%C = zext <2 x i32> %A to <2 x i128>

llvm/test/Transforms/InstCombine/trunc.ll

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -345,7 +345,7 @@ define i64 @test11(i32 %A, i32 %B) {
345345
; CHECK-NEXT: [[C:%.*]] = zext i32 [[A:%.*]] to i64
346346
; CHECK-NEXT: [[TMP1:%.*]] = and i32 [[B:%.*]], 31
347347
; CHECK-NEXT: [[E:%.*]] = zext i32 [[TMP1]] to i64
348-
; CHECK-NEXT: [[F:%.*]] = shl i64 [[C]], [[E]]
348+
; CHECK-NEXT: [[F:%.*]] = shl nuw nsw i64 [[C]], [[E]]
349349
; CHECK-NEXT: ret i64 [[F]]
350350
;
351351
%C = zext i32 %A to i128
@@ -361,7 +361,7 @@ define <2 x i64> @test11_vec(<2 x i32> %A, <2 x i32> %B) {
361361
; CHECK-NEXT: [[C:%.*]] = zext <2 x i32> [[A:%.*]] to <2 x i64>
362362
; CHECK-NEXT: [[TMP1:%.*]] = and <2 x i32> [[B:%.*]], <i32 31, i32 31>
363363
; CHECK-NEXT: [[E:%.*]] = zext <2 x i32> [[TMP1]] to <2 x i64>
364-
; CHECK-NEXT: [[F:%.*]] = shl <2 x i64> [[C]], [[E]]
364+
; CHECK-NEXT: [[F:%.*]] = shl nuw nsw <2 x i64> [[C]], [[E]]
365365
; CHECK-NEXT: ret <2 x i64> [[F]]
366366
;
367367
%C = zext <2 x i32> %A to <2 x i128>
@@ -377,7 +377,7 @@ define <2 x i64> @test11_vec_nonuniform(<2 x i32> %A, <2 x i32> %B) {
377377
; CHECK-NEXT: [[C:%.*]] = zext <2 x i32> [[A:%.*]] to <2 x i64>
378378
; CHECK-NEXT: [[TMP1:%.*]] = and <2 x i32> [[B:%.*]], <i32 31, i32 15>
379379
; CHECK-NEXT: [[E:%.*]] = zext <2 x i32> [[TMP1]] to <2 x i64>
380-
; CHECK-NEXT: [[F:%.*]] = shl <2 x i64> [[C]], [[E]]
380+
; CHECK-NEXT: [[F:%.*]] = shl nuw nsw <2 x i64> [[C]], [[E]]
381381
; CHECK-NEXT: ret <2 x i64> [[F]]
382382
;
383383
%C = zext <2 x i32> %A to <2 x i128>

0 commit comments

Comments
 (0)