diff --git a/llvm/lib/Transforms/Scalar/GVN.cpp b/llvm/lib/Transforms/Scalar/GVN.cpp --- a/llvm/lib/Transforms/Scalar/GVN.cpp +++ b/llvm/lib/Transforms/Scalar/GVN.cpp @@ -946,6 +946,7 @@ // Loading the allocation -> undef. if (isa(DepInst) || isMallocLikeFn(DepInst, TLI) || + isAlignedAllocLikeFn(DepInst, TLI) || // Loading immediately after lifetime begin -> undef. isLifetimeStart(DepInst)) { Res = AvailableValue::get(UndefValue::get(LI->getType())); @@ -1450,7 +1451,7 @@ Value *LHS = Cmp->getOperand(0); Value *RHS = Cmp->getOperand(1); // If we can prove either side non-zero, then equality must imply - // equivalence. + // equivalence. // FIXME: We should do this optimization if 'no signed zeros' is // applicable via an instruction-level fast-math-flag or some other // indicator that relaxed FP semantics are being used. @@ -1515,10 +1516,10 @@ // If we find an equality fact, canonicalize all dominated uses in this block // to one of the two values. We heuristically choice the "oldest" of the // two where age is determined by value number. (Note that propagateEquality - // above handles the cross block case.) - // + // above handles the cross block case.) + // // Key case to cover are: - // 1) + // 1) // %cmp = fcmp oeq float 3.000000e+00, %0 ; const on lhs could happen // call void @llvm.assume(i1 %cmp) // ret float %0 ; will change it to ret float 3.000000e+00 @@ -1559,7 +1560,7 @@ << *CmpLHS << " with " << *CmpRHS << " in block " << IntrinsicI->getParent()->getName() << "\n"); - + // Setup the replacement map - this handles uses within the same block if (hasUsersIn(CmpLHS, IntrinsicI->getParent())) @@ -1824,7 +1825,7 @@ bool GVN::replaceOperandsForInBlockEquality(Instruction *Instr) const { bool Changed = false; for (unsigned OpNum = 0; OpNum < Instr->getNumOperands(); ++OpNum) { - Value *Operand = Instr->getOperand(OpNum); + Value *Operand = Instr->getOperand(OpNum); auto it = ReplaceOperandsWithMap.find(Operand); if (it != ReplaceOperandsWithMap.end()) { LLVM_DEBUG(dbgs() << "GVN replacing: " << *Operand << " with " @@ -1944,7 +1945,7 @@ // If "A == B" is known true, or "A != B" is known false, then replace // A with B everywhere in the scope. For floating point operations, we - // have to be careful since equality does not always imply equivalance. + // have to be careful since equality does not always imply equivalance. if ((isKnownTrue && impliesEquivalanceIfTrue(Cmp)) || (isKnownFalse && impliesEquivalanceIfFalse(Cmp))) Worklist.push_back(std::make_pair(Op0, Op1)); diff --git a/llvm/test/Transforms/GVN/malloc-load-removal.ll b/llvm/test/Transforms/GVN/malloc-load-removal.ll --- a/llvm/test/Transforms/GVN/malloc-load-removal.ll +++ b/llvm/test/Transforms/GVN/malloc-load-removal.ll @@ -54,3 +54,28 @@ ; CHECK_NO_LIBCALLS: load ; CHECK_NO_LIBCALLS: icmp } + +declare i8* @aligned_alloc(i64, i64) nounwind + +define noalias i8* @test3() nounwind uwtable ssp { +entry: + %call = tail call i8* @aligned_alloc(i64 256, i64 32) nounwind + %0 = load i8, i8* %call, align 32 + %tobool = icmp eq i8 %0, 0 + br i1 %tobool, label %if.end, label %if.then + +if.then: ; preds = %entry + store i8 0, i8* %call, align 1 + br label %if.end + +if.end: ; preds = %if.then, %entry + ret i8* %call + +; CHECK-LABEL: @test3( +; CHECK-NOT: load +; CHECK-NOT: icmp + +; CHECK_NO_LIBCALLS-LABEL: @test3( +; CHECK_NO_LIBCALLS: load +; CHECK_NO_LIBCALLS: icmp +}