Index: lib/Target/SystemZ/SystemZISelLowering.cpp =================================================================== --- lib/Target/SystemZ/SystemZISelLowering.cpp +++ lib/Target/SystemZ/SystemZISelLowering.cpp @@ -1844,11 +1844,14 @@ ISD::SEXTLOAD : ISD::ZEXTLOAD); if (C.Op0.getValueType() != MVT::i32 || - Load->getExtensionType() != ExtType) + Load->getExtensionType() != ExtType) { C.Op0 = DAG.getExtLoad(ExtType, SDLoc(Load), MVT::i32, Load->getChain(), Load->getBasePtr(), Load->getPointerInfo(), Load->getMemoryVT(), Load->getAlignment(), Load->getMemOperand()->getFlags()); + // Update the chain uses. + DAG.ReplaceAllUsesOfValueWith(SDValue(Load, 1), C.Op0.getValue(1)); + } // Make sure that the second operand is an i32 with the right value. if (C.Op1.getValueType() != MVT::i32 || @@ -2940,9 +2943,13 @@ // but we need this case for bitcasts that are created during lowering // and which are then lowered themselves. if (auto *LoadN = dyn_cast(In)) - if (ISD::isNormalLoad(LoadN)) - return DAG.getLoad(ResVT, DL, LoadN->getChain(), LoadN->getBasePtr(), - LoadN->getMemOperand()); + if (ISD::isNormalLoad(LoadN)) { + SDValue NewLoad = DAG.getLoad(ResVT, DL, LoadN->getChain(), + LoadN->getBasePtr(), LoadN->getMemOperand()); + // Update the chain uses. + DAG.ReplaceAllUsesOfValueWith(SDValue(LoadN, 1), NewLoad.getValue(1)); + return NewLoad; + } if (InVT == MVT::i32 && ResVT == MVT::f32) { SDValue In64; Index: test/CodeGen/SystemZ/dag-combine-02.ll =================================================================== --- /dev/null +++ test/CodeGen/SystemZ/dag-combine-02.ll @@ -0,0 +1,192 @@ +; Test that adjustSubwordCmp() maintains the chains properly when creating a +; new extending load. +; +; RUN: llc < %s -mtriple=s390x-linux-gnu -mcpu=z13 -O3 | FileCheck %s + +@g_56 = external hidden unnamed_addr global i64, align 8 +@func_22.l_91 = external hidden unnamed_addr constant [4 x [7 x i16*]], align 8 +@g_102 = external hidden unnamed_addr global i16**, align 8 +@.str = external hidden unnamed_addr constant [2 x i8], align 2 +@.str.1 = external hidden unnamed_addr constant [15 x i8], align 2 +@crc32_context = external hidden unnamed_addr global i32, align 4 +@crc32_tab = external hidden unnamed_addr global [256 x i32], align 4 +@.str.2 = external hidden unnamed_addr constant [36 x i8], align 2 +@.str.3 = external hidden unnamed_addr constant [15 x i8], align 2 +@g_181.0.4.5 = external hidden unnamed_addr global i1, align 2 + +; Function Attrs: argmemonly nounwind +declare void @llvm.lifetime.start.p0i8(i64, i8* nocapture) #0 + +; Function Attrs: argmemonly nounwind +declare void @llvm.memcpy.p0i8.p0i8.i64(i8* nocapture writeonly, i8* nocapture readonly, i64, i32, i1) #0 + +; Function Attrs: argmemonly nounwind +declare void @llvm.lifetime.end.p0i8(i64, i8* nocapture) #0 + +; Function Attrs: nounwind +define signext i32 @main(i32 signext, i8** nocapture readonly) local_unnamed_addr #1 { + %3 = alloca [4 x [7 x i16*]], align 8 + %4 = icmp eq i32 %0, 2 + br i1 %4, label %5, label %11 + +;