Index: lib/Target/SystemZ/SystemZISelLowering.cpp =================================================================== --- lib/Target/SystemZ/SystemZISelLowering.cpp +++ lib/Target/SystemZ/SystemZISelLowering.cpp @@ -1844,11 +1844,17 @@ 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()); + // Make sure successors of the original load stay after the new load by + // updating them to use the new values. + SDValue From[] = {SDValue(Load, 0), SDValue(Load, 1)}; + SDValue To[] = {SDValue(C.Op0.getNode(), 0), SDValue(C.Op0.getNode(), 1)}; + DAG.ReplaceAllUsesOfValuesWith(From, To, 2); + } // Make sure that the second operand is an i32 with the right value. if (C.Op1.getValueType() != MVT::i32 || 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 + +;