Index: llvm/trunk/lib/Transforms/Scalar/NewGVN.cpp =================================================================== --- llvm/trunk/lib/Transforms/Scalar/NewGVN.cpp +++ llvm/trunk/lib/Transforms/Scalar/NewGVN.cpp @@ -1086,9 +1086,13 @@ CongruenceClass *CC = ValueToClass.lookup(V); if (CC) { if (CC->getLeader() && CC->getLeader() != I) { - // Don't add temporary instructions to the user lists. - if (!AllTempInstructions.count(I)) - addAdditionalUsers(V, I); + // If we simplified to something else, we need to communicate + // that we're users of the value we simplified to. + if (I != V) { + // Don't add temporary instructions to the user lists. + if (!AllTempInstructions.count(I)) + addAdditionalUsers(V, I); + } return createVariableOrConstant(CC->getLeader()); } if (CC->getDefiningExpr()) { Index: llvm/trunk/test/Transforms/NewGVN/simp-to-self.ll =================================================================== --- llvm/trunk/test/Transforms/NewGVN/simp-to-self.ll +++ llvm/trunk/test/Transforms/NewGVN/simp-to-self.ll @@ -0,0 +1,27 @@ +; RUN: opt -S < %s -newgvn | FileCheck %s + +; CHECK-LABEL: for.cond: +; CHECK-NEXT: %lv = load i32, i32* bitcast (i64* @a to i32*) +; CHECK-NEXT: %bf.clear = and i32 %lv, -131072 +; CHECK-NEXT: %bf.set = or i32 1, %bf.clear +; CHECK-NEXT: br i1 %bc, label %for.cond, label %exit +@a = external global i64 + +define void @fn1(i1 %bc) { +entry: + br label %for.cond + +for.cond: ; preds = %for.cond1.1, %entry + %tmp = phi i1 [ undef, %entry ], [ 1, %for.cond ] + %conv = zext i1 %tmp to i32 + %lv = load i32, i32* bitcast (i64* @a to i32*) + %bf.clear = and i32 %lv, -131072 + %bf.set = or i32 %conv, %bf.clear + %bf.clear.1 = and i32 %bf.set, -131072 + %bf.set.1 = or i32 1, %bf.clear.1 + br i1 %bc, label %for.cond, label %exit + +exit: ; preds = %for.cond1 + store i32 %bf.set.1, i32* bitcast (i64* @a to i32*) + ret void +}