Index: llvm/include/llvm/CodeGen/SelectionDAGNodes.h =================================================================== --- llvm/include/llvm/CodeGen/SelectionDAGNodes.h +++ llvm/include/llvm/CodeGen/SelectionDAGNodes.h @@ -867,6 +867,14 @@ } for (const SDValue &OpV : M->op_values()) { SDNode *Op = OpV.getNode(); + // If we are adding a glued node, its glued user should be considered a + // predecessor as well to prevent a node merge causing a non-immediate + // use of a glue operand. Walk down all unvisited glue users. + while (auto *GN = Op->getGluedUser()) { + if ((GN == M) || Visited.count(GN)) + break; + Op = GN; + } if (Visited.insert(Op).second) Worklist.push_back(Op); if (Op == N) Index: llvm/test/CodeGen/AVR/glue-dag-combine-bug.ll =================================================================== --- /dev/null +++ llvm/test/CodeGen/AVR/glue-dag-combine-bug.ll @@ -0,0 +1,51 @@ +; RUN: llc < %s -mtriple=avr-unknown-unknown + +%"foo" = type { [0 x i8], i16, [0 x i8], [40 x i32], [0 x i8] } + +define void @bar() unnamed_addr addrspace(0) #0 personality i32 (...) addrspace(1)* @rust_eh_personality { +start: + %_7.sroa.0.0..sroa_idx.i = getelementptr inbounds %"foo", %"foo"* undef, i16 0, i32 3, i16 0 + switch i2 undef, label %bb5.i2 [ + i2 0, label %bb2.i + i2 1, label %bb3.i + i2 -2, label %bb4.i + ] + +bb2.i: ; preds = %start + unreachable + +bb3.i: ; preds = %start + unreachable + +bb4.i: ; preds = %start + br i1 undef, label %bb7, label %bb9.i5.i + +bb9.i5.i: ; preds = %bb4.i + %0 = call addrspace(1) { i8, i1 } @llvm.usub.with.overflow.i8(i8 0, i8 48) + %1 = extractvalue { i8, i1 } %0, 0 + %2 = zext i8 %1 to i32 + %3 = load i32, i32* %_7.sroa.0.0..sroa_idx.i, align 1 + %4 = call addrspace(1) { i32, i1 } @llvm.uadd.with.overflow.i32(i32 %3, i32 %2) #3 + %5 = extractvalue { i32, i1 } %4, 0 + store i32 %5, i32* %_7.sroa.0.0..sroa_idx.i, align 1 + unreachable + +bb5.i2: ; preds = %start + unreachable + +bb7: ; preds = %bb4.i + ret void +} + +; Function Attrs: nounwind readnone speculatable +declare { i8, i1 } @llvm.usub.with.overflow.i8(i8, i8) addrspace(1) #1 + +declare i32 @rust_eh_personality(...) unnamed_addr addrspace(1) #2 + +; Function Attrs: nounwind readnone speculatable +declare { i32, i1 } @llvm.uadd.with.overflow.i32(i32, i32) addrspace(1) #1 + +attributes #0 = { uwtable } +attributes #1 = { nounwind readnone speculatable } +attributes #2 = { "target-cpu"="atmega32u4" } +attributes #3 = { nounwind }