Index: lib/Transforms/InstCombine/InstCombineCasts.cpp =================================================================== --- lib/Transforms/InstCombine/InstCombineCasts.cpp +++ lib/Transforms/InstCombine/InstCombineCasts.cpp @@ -1088,6 +1088,21 @@ uint32_t SrcBitsKept = SrcTy->getScalarSizeInBits()-BitsToClear; uint32_t DestBitSize = DestTy->getScalarSizeInBits(); + // Since the old instruction is merged, we preserve it's DI as + // a fragment in the resulting instruction + SmallVector SrcDbgInsts; + findDbgUsers(SrcDbgInsts, Src); + if (SrcDbgInsts.size()) { + DIBuilder DIB(*CI.getModule()); + for (auto *DII : SrcDbgInsts) { + auto Fragment = DIExpression::createFragmentExpression( + DII->getExpression(), SrcBitsKept, DestBitSize); + DIB.insertDbgValueIntrinsic( + Res, DII->getVariable(), Fragment.getValue(), + DII->getDebugLoc().get(), &*std::next(CI.getIterator())); + } + } + // If the high bits are already filled with zeros, just replace this // cast with the result. if (MaskedValueIsZero(Res, Index: test/Transforms/InstCombine/debuginfo-trunc-and-zext.ll =================================================================== --- /dev/null +++ test/Transforms/InstCombine/debuginfo-trunc-and-zext.ll @@ -0,0 +1,12 @@ +; RUN: opt -debugify -instcombine -S < %s | FileCheck %s + +define <2 x i64> @test3(<2 x i64> %A) { + %trunc = trunc <2 x i64> %A to <2 x i32> + %and = and <2 x i32> %trunc, + %zext = zext <2 x i32> %and to <2 x i64> + ret <2 x i64> %zext +} + +; CHECK: call void @llvm.dbg.value{{.*}} +; CHECK: call void @llvm.dbg.value{{.*}} +; CHECK: call void @llvm.dbg.value{{.*}}