File tree Expand file tree Collapse file tree 2 files changed +18
-2
lines changed
lib/Transforms/InstCombine
test/Transforms/InstCombine Expand file tree Collapse file tree 2 files changed +18
-2
lines changed Original file line number Diff line number Diff line change @@ -1561,8 +1561,13 @@ Instruction *InstCombinerImpl::visitSExt(SExtInst &Sext) {
15611561 // If the input has more sign bits than bits truncated, then convert
15621562 // directly to final type.
15631563 unsigned XBitSize = X->getType ()->getScalarSizeInBits ();
1564- if (ComputeNumSignBits (X, &Sext) > XBitSize - SrcBitSize)
1565- return CastInst::CreateIntegerCast (X, DestTy, /* isSigned */ true );
1564+ bool HasNSW = cast<TruncInst>(Src)->hasNoSignedWrap ();
1565+ if (HasNSW || (ComputeNumSignBits (X, &Sext) > XBitSize - SrcBitSize)) {
1566+ auto *Res = CastInst::CreateIntegerCast (X, DestTy, /* isSigned */ true );
1567+ if (auto *ResTrunc = dyn_cast<TruncInst>(Res); ResTrunc && HasNSW)
1568+ ResTrunc->setHasNoSignedWrap (true );
1569+ return Res;
1570+ }
15661571
15671572 // If input is a trunc from the destination type, then convert into shifts.
15681573 if (Src->hasOneUse () && X->getType () == DestTy) {
Original file line number Diff line number Diff line change @@ -144,6 +144,17 @@ define i24 @wide_source_matching_signbits(i32 %x) {
144144 ret i24 %c
145145}
146146
147+ define i32 @wide_source_matching_signbits_has_nsw_flag (i64 %i ) {
148+ ; CHECK-LABEL: define i32 @wide_source_matching_signbits_has_nsw_flag(
149+ ; CHECK-SAME: i64 [[I:%.*]]) {
150+ ; CHECK-NEXT: [[A:%.*]] = trunc nsw i64 [[I]] to i32
151+ ; CHECK-NEXT: ret i32 [[A]]
152+ ;
153+ %a = trunc nsw i64 %i to i16
154+ %b = sext i16 %a to i32
155+ ret i32 %b
156+ }
157+
147158; negative test - not enough sign-bits
148159
149160define i24 @wide_source_not_matching_signbits (i32 %x ) {
You can’t perform that action at this time.
0 commit comments