diff --git a/lib/Transforms/Scalar/GVN.cpp b/lib/Transforms/Scalar/GVN.cpp index ed4e0d61488..783da6a5635 100644 --- a/lib/Transforms/Scalar/GVN.cpp +++ b/lib/Transforms/Scalar/GVN.cpp @@ -1384,15 +1384,19 @@ bool GVN::processNonLocalLoad(LoadInst *LI, MemDepResult DepInfo = Deps[i].getResult(); if (DepInfo.isClobber()) { + // The address being loaded in this non-local block may not be the same as + // the pointer operand of the load if PHI translation occurs. Make sure + // to consider the right address. + Value *Address = Deps[i].getAddress(); + // If the dependence is to a store that writes to a superset of the bits // read by the load, we can extract the bits we need for the load from the // stored value. if (StoreInst *DepSI = dyn_cast(DepInfo.getInst())) { if (TD == 0) TD = getAnalysisIfAvailable(); - if (TD) { - int Offset = AnalyzeLoadFromClobberingStore(LI->getType(), - LI->getPointerOperand(), + if (TD && Address) { + int Offset = AnalyzeLoadFromClobberingStore(LI->getType(), Address, DepSI, *TD); if (Offset != -1) { ValuesPerBlock.push_back(AvailableValueInBlock::get(DepBB, @@ -1408,9 +1412,8 @@ bool GVN::processNonLocalLoad(LoadInst *LI, if (MemIntrinsic *DepMI = dyn_cast(DepInfo.getInst())) { if (TD == 0) TD = getAnalysisIfAvailable(); - if (TD) { - int Offset = AnalyzeLoadFromClobberingMemInst(LI->getType(), - LI->getPointerOperand(), + if (TD && Address) { + int Offset = AnalyzeLoadFromClobberingMemInst(LI->getType(), Address, DepMI, *TD); if (Offset != -1) { ValuesPerBlock.push_back(AvailableValueInBlock::getMI(DepBB, DepMI, diff --git a/test/Transforms/GVN/rle.ll b/test/Transforms/GVN/rle.ll index 46fc818daa3..d419fd24240 100644 --- a/test/Transforms/GVN/rle.ll +++ b/test/Transforms/GVN/rle.ll @@ -469,6 +469,9 @@ exit: define i8 @phi_trans4(i8* %p) { ; CHECK: @phi_trans4 entry: + %X3 = getelementptr i8* %p, i32 192 + store i8 192, i8* %X3 + %X = getelementptr i8* %p, i32 4 %Y = load i8* %X br label %loop @@ -476,11 +479,15 @@ entry: loop: %i = phi i32 [4, %entry], [192, %loop] %X2 = getelementptr i8* %p, i32 %i - %Y2 = load i8* %X + %Y2 = load i8* %X2 + +; CHECK: loop: +; CHECK-NEXT: %Y2 = phi i8 [ %Y, %entry ], [ 0, %loop ] +; CHECK-NOT: load i8 %cond = call i1 @cond2() - %Z = bitcast i8 *%X2 to i32* + %Z = bitcast i8 *%X3 to i32* store i32 0, i32* %Z br i1 %cond, label %loop, label %out @@ -492,6 +499,7 @@ out: define i8 @phi_trans5(i8* %p) { ; CHECK: @phi_trans5 entry: + %X4 = getelementptr i8* %p, i32 2 store i8 19, i8* %X4 @@ -502,8 +510,7 @@ entry: loop: %i = phi i32 [4, %entry], [3, %cont] %X2 = getelementptr i8* %p, i32 %i - %Y2 = load i8* %X2 - ;; FIXME: This load is being incorrectly replaced! + %Y2 = load i8* %X2 ; Ensure this load is not being incorrectly replaced. %cond = call i1 @cond2() br i1 %cond, label %cont, label %out @@ -511,6 +518,11 @@ cont: %Z = getelementptr i8* %X2, i32 -1 %Z2 = bitcast i8 *%Z to i32* store i32 50462976, i32* %Z2 ;; (1 << 8) | (2 << 16) | (3 << 24) + + +; CHECK: store i32 +; CHECK-NEXT: getelementptr i8* %p, i32 3 +; CHECK-NEXT: load i8* br label %loop out: