Index: lib/Transforms/InstCombine/InstCombineCasts.cpp =================================================================== --- lib/Transforms/InstCombine/InstCombineCasts.cpp +++ lib/Transforms/InstCombine/InstCombineCasts.cpp @@ -1083,6 +1083,23 @@ uint32_t SrcBitsKept = SrcTy->getScalarSizeInBits()-BitsToClear; uint32_t DestBitSize = DestTy->getScalarSizeInBits(); + // When the DestTy is integer, try to preserve + // any debug values referring to the zext being replaced + if (DestTy->isIntegerTy()) { + insertReplacementDbgValues( + *Src, *Res, *std::next(CI.getIterator()), + [&](DbgInfoIntrinsic &OldDII) -> DIExpression * { + auto DIExp = OldDII.getExpression(); + if (DIExp) { + return DIExpression::createFragmentExpression( + DIExp, DestBitSize - SrcBitsKept, + SrcTy->getScalarSizeInBits()) + .getValue(); + } + return nullptr; + }); + } + // 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,29 @@ +; RUN: opt -debugify -instcombine -S < %s | FileCheck %s + +target datalayout = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128-n8:16:32" + +; Test that when zext is evaluated in different type +; we preserve the debug information via fragments + +define i32 @test-scalar(i32 %x, i32 %y) { + %A = trunc i32 %x to i8 + %B = trunc i32 %y to i8 + %C = mul i8 %A, %B + %D = zext i8 %C to i32 + ret i32 %D +} + +; CHECK: define i32 @test-scalar +; CHECK: call void @llvm.dbg.value({{.*}}, metadata !DIExpression(DW_OP_LLVM_fragment, 24, 8)){{.*}} + +; TODO vector version + +; define <2 x i64> @test-vector(<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-LABEL: define <2 x i64> @test-non-vector +; CHECK: call void @llvm.dbg.value({{.*}}, metadata !DIExpression(DW_OP_LLVM_fragment, {{.*}}