Index: lib/Analysis/MemoryDependenceAnalysis.cpp =================================================================== --- lib/Analysis/MemoryDependenceAnalysis.cpp +++ lib/Analysis/MemoryDependenceAnalysis.cpp @@ -234,26 +234,6 @@ return MemDepResult::getNonFuncLocal(); } -/// Return true if LI is a load that would fully overlap MemLoc if done as -/// a wider legal integer load. -/// -/// MemLocBase, MemLocOffset are lazily computed here the first time the -/// base/offs of memloc is needed. -static bool isLoadLoadClobberIfExtendedToFullWidth(const MemoryLocation &MemLoc, - const Value *&MemLocBase, - int64_t &MemLocOffs, - const LoadInst *LI) { - const DataLayout &DL = LI->getModule()->getDataLayout(); - - // If we haven't already computed the base/offset of MemLoc, do so now. - if (!MemLocBase) - MemLocBase = GetPointerBaseWithConstantOffset(MemLoc.Ptr, MemLocOffs, DL); - - unsigned Size = MemoryDependenceResults::getLoadLoadClobberFullWidthSize( - MemLocBase, MemLocOffs, MemLoc.Size, LI); - return Size != 0; -} - unsigned MemoryDependenceResults::getLoadLoadClobberFullWidthSize( const Value *MemLocBase, int64_t MemLocOffs, unsigned MemLocSize, const LoadInst *LI) { @@ -410,9 +390,6 @@ MemDepResult MemoryDependenceResults::getSimplePointerDependencyFrom( const MemoryLocation &MemLoc, bool isLoad, BasicBlock::iterator ScanIt, BasicBlock *BB, Instruction *QueryInst, unsigned *Limit) { - - const Value *MemLocBase = nullptr; - int64_t MemLocOffset = 0; bool isInvariantLoad = false; if (!Limit) { @@ -550,21 +527,8 @@ AliasResult R = AA.alias(LoadLoc, MemLoc); if (isLoad) { - if (R == NoAlias) { - // If this is an over-aligned integer load (for example, - // "load i8* %P, align 4") see if it would obviously overlap with the - // queried location if widened to a larger load (e.g. if the queried - // location is 1 byte at P+1). If so, return it as a load/load - // clobber result, allowing the client to decide to widen the load if - // it wants to. - if (IntegerType *ITy = dyn_cast(LI->getType())) { - if (LI->getAlignment() * 8 > ITy->getPrimitiveSizeInBits() && - isLoadLoadClobberIfExtendedToFullWidth(MemLoc, MemLocBase, - MemLocOffset, LI)) - return MemDepResult::getClobber(Inst); - } + if (R == NoAlias) continue; - } // Must aliased loads are defs of each other. if (R == MustAlias) Index: lib/Transforms/Scalar/GVN.cpp =================================================================== --- lib/Transforms/Scalar/GVN.cpp +++ lib/Transforms/Scalar/GVN.cpp @@ -910,40 +910,6 @@ StorePtr, StoreSize, DL); } -/// This function is called when we have a -/// memdep query of a load that ends up being clobbered by another load. See if -/// the other load can feed into the second load. -static int AnalyzeLoadFromClobberingLoad(Type *LoadTy, Value *LoadPtr, - LoadInst *DepLI, const DataLayout &DL){ - // Cannot handle reading from store of first-class aggregate yet. - if (DepLI->getType()->isStructTy() || DepLI->getType()->isArrayTy()) - return -1; - - Value *DepPtr = DepLI->getPointerOperand(); - uint64_t DepSize = DL.getTypeSizeInBits(DepLI->getType()); - int R = AnalyzeLoadFromClobberingWrite(LoadTy, LoadPtr, DepPtr, DepSize, DL); - if (R != -1) return R; - - // If we have a load/load clobber an DepLI can be widened to cover this load, - // then we should widen it! - int64_t LoadOffs = 0; - const Value *LoadBase = - GetPointerBaseWithConstantOffset(LoadPtr, LoadOffs, DL); - unsigned LoadSize = DL.getTypeStoreSize(LoadTy); - - unsigned Size = MemoryDependenceResults::getLoadLoadClobberFullWidthSize( - LoadBase, LoadOffs, LoadSize, DepLI); - if (Size == 0) return -1; - - // Check non-obvious conditions enforced by MDA which we rely on for being - // able to materialize this potentially available value - assert(DepLI->isSimple() && "Cannot widen volatile/atomic load!"); - assert(DepLI->getType()->isIntegerTy() && "Can't widen non-integer load"); - - return AnalyzeLoadFromClobberingWrite(LoadTy, LoadPtr, DepPtr, Size*8, DL); -} - - static int AnalyzeLoadFromClobberingMemInst(Type *LoadTy, Value *LoadPtr, MemIntrinsic *MI, @@ -1257,25 +1223,6 @@ } } - // Check to see if we have something like this: - // load i32* P - // load i8* (P+1) - // if we have this, replace the later with an extraction from the former. - if (LoadInst *DepLI = dyn_cast(DepInfo.getInst())) { - // If this is a clobber and L is the first instruction in its block, then - // we have the first instruction in the entry block. - // Can't forward from non-atomic to atomic without violating memory model. - if (DepLI != LI && Address && LI->isAtomic() <= DepLI->isAtomic()) { - int Offset = - AnalyzeLoadFromClobberingLoad(LI->getType(), Address, DepLI, DL); - - if (Offset != -1) { - Res = AvailableValue::getLoad(DepLI, Offset); - return true; - } - } - } - // If the clobbering value is a memset/memcpy/memmove, see if we can // forward a value on from it. if (MemIntrinsic *DepMI = dyn_cast(DepInfo.getInst())) { Index: test/Instrumentation/AddressSanitizer/asan-vs-gvn.ll =================================================================== --- test/Instrumentation/AddressSanitizer/asan-vs-gvn.ll +++ test/Instrumentation/AddressSanitizer/asan-vs-gvn.ll @@ -34,7 +34,7 @@ ret void } -;; Accessing bytes 4 and 5. Ok to widen to i16. +;; Accessing bytes 4 and 5. No widen to i16. define i32 @test_widening_ok(i8* %P) nounwind ssp noredzone sanitize_address { entry: @@ -45,7 +45,8 @@ %add = add nsw i32 %conv, %conv2 ret i32 %add ; CHECK: @test_widening_ok -; CHECK: __asan_report_load2 +; CHECK: __asan_report_load1 +; CHECK: __asan_report_load1 ; CHECK-NOT: __asan_report ; CHECK: end_test_widening_ok } Index: test/Transforms/GVN/PRE/atomic.ll =================================================================== --- test/Transforms/GVN/PRE/atomic.ll +++ test/Transforms/GVN/PRE/atomic.ll @@ -121,18 +121,7 @@ } ; CHECK-LABEL: @test13( -; atomic to non-atomic forwarding is legal define i32 @test13(i32* %P1) { - %a = load atomic i32, i32* %P1 seq_cst, align 4 - %b = load i32, i32* %P1 - %res = sub i32 %a, %b - ret i32 %res - ; CHECK: load atomic i32, i32* %P1 - ; CHECK: ret i32 0 -} - -; CHECK-LABEL: @test13b( -define i32 @test13b(i32* %P1) { store atomic i32 0, i32* %P1 unordered, align 4 %b = load i32, i32* %P1 ret i32 %b @@ -147,7 +136,8 @@ %res = sub i32 %a, %b ret i32 %res ; CHECK: load atomic i32, i32* %P1 seq_cst - ; CHECK-NEXT: ret i32 0 + ; CHECK-NEXT: load atomic i32 + ; CHECK: ret i32 %res } ; CHECK-LABEL: @test15( @@ -487,8 +477,7 @@ define i32 @non_local_pre6(i32* %P1) { ; CHECK-LABEL: @non_local_pre6( ; CHECK: load atomic i32, i32* %P1 seq_cst -; CHECK: load atomic i32, i32* %P1 unordered -; CHECK: %b = phi i32 [ %b.pre, %early ], [ %a, %0 ] +; CHECK: %b = load atomic i32, i32* %P1 unordered ; CHECK: ret i32 %b %a = load atomic i32, i32* %P1 seq_cst, align 4 %cmp = icmp eq i32 %a, 0 Index: test/Transforms/GVN/PRE/load-pre-nonlocal.ll =================================================================== --- test/Transforms/GVN/PRE/load-pre-nonlocal.ll +++ test/Transforms/GVN/PRE/load-pre-nonlocal.ll @@ -51,15 +51,16 @@ } ; %1 is partially redundant if %0 can be widened to a 64-bit load. +; But we should not widen %0 to 64-bit load. ; CHECK-LABEL: define i32 @overaligned_load ; CHECK: if.then: -; CHECK: %0 = load i64 -; CHECK: [[LSHR:%[0-9]+]] = lshr i64 %0, 32, !dbg [[LSHR_LOC:![0-9]+]] -; CHECK: trunc i64 [[LSHR]] to i32 +; CHECK-NOT: %0 = load i64 +; CHECK-NOT: [[LSHR:%[0-9]+]] = lshr i64 %0, 32, !dbg [[LSHR_LOC:![0-9]+]] +; CHECK-NOT: trunc i64 [[LSHR]] to i32 ; CHECK: if.end: -; CHECK-NOT: %1 = load i32, i32* -; CHECK: [[LSHR_LOC]] = !DILocation(line: 101, column: 1, scope: !{{.*}}) +; CHECK: %1 = load i32, i32* +; CHECK-NOT: [[LSHR_LOC]] = !DILocation(line: 101, column: 1, scope: !{{.*}}) define i32 @overaligned_load(i32 %a, i32* nocapture %b) !dbg !13 { entry: Index: test/Transforms/GVN/PRE/rle.ll =================================================================== --- test/Transforms/GVN/PRE/rle.ll +++ test/Transforms/GVN/PRE/rle.ll @@ -640,7 +640,8 @@ ret i32 %add ; CHECK-LABEL: @test_widening1( ; CHECK-NOT: load -; CHECK: load i16, i16* +; CHECK: load i8, i8* +; CHECK: load i8, i8* ; CHECK-NOT: load ; CHECK: ret i32 } @@ -664,7 +665,10 @@ ret i32 %add3 ; CHECK-LABEL: @test_widening2( ; CHECK-NOT: load -; CHECK: load i32, i32* +; CHECK: load i8, i8* +; CHECK: load i8, i8* +; CHECK: load i8, i8* +; CHECK: load i8, i8* ; CHECK-NOT: load ; CHECK: ret i32 } Index: test/Transforms/GVN/big-endian.ll =================================================================== --- test/Transforms/GVN/big-endian.ll +++ test/Transforms/GVN/big-endian.ll @@ -7,9 +7,9 @@ ;; loads reusing a load value. define i64 @test1({ i1, i8 }* %predA, { i1, i8 }* %predB) { ; CHECK-LABEL: @test1 -; CHECK: [[V1:%.*]] = load i16, i16* %{{.*}} -; CHECK: [[V2:%.*]] = lshr i16 [[V1]], 8 -; CHECK: trunc i16 [[V2]] to i1 +; CHECK-NOT: [[V1:%.*]] = load i16, i16* %{{.*}} +; CHECK-NOT: [[V2:%.*]] = lshr i16 [[V1]], 8 +; CHECK-NOT: trunc i16 [[V2]] to i1 %valueLoadA.fca.0.gep = getelementptr inbounds { i1, i8 }, { i1, i8 }* %predA, i64 0, i32 0 %valueLoadA.fca.0.load = load i1, i1* %valueLoadA.fca.0.gep, align 8 Index: test/Transforms/GVN/no_speculative_loads_with_asan.ll =================================================================== --- test/Transforms/GVN/no_speculative_loads_with_asan.ll +++ test/Transforms/GVN/no_speculative_loads_with_asan.ll @@ -25,9 +25,7 @@ } ; CHECK-LABEL: @TestNoAsan -; CHECK: %[[LOAD:[^ ]+]] = load i32 -; CHECK: {{.*}} = ashr i32 %[[LOAD]] -; CHECK-NOT: {{.*}} = phi +; CHECK: ret i32 0 define i32 @TestAsan() sanitize_address { %1 = tail call noalias i8* @_Znam(i64 2) Index: test/Transforms/GVN/pr25440.ll =================================================================== --- test/Transforms/GVN/pr25440.ll +++ test/Transforms/GVN/pr25440.ll @@ -19,7 +19,7 @@ %x.tr = phi %struct.a* [ %x, %entry ], [ null, %land.lhs.true ] %code1 = getelementptr inbounds %struct.a, %struct.a* %x.tr, i32 0, i32 0 %0 = load i16, i16* %code1, align 4 -; CHECK: load i32, i32* +; CHECK: load i16, i16* %conv = zext i16 %0 to i32 switch i32 %conv, label %if.end.50 [ i32 43, label %cleanup @@ -38,7 +38,7 @@ cond.false: ; preds = %if.then.26 ; CHECK: cond.false: -; CHECK-NOT: load +; CHECK: load i16 %mode = getelementptr inbounds %struct.a, %struct.a* %x.tr.lcssa163, i32 0, i32 1 %bf.load = load i16, i16* %mode, align 2 %bf.shl = shl i16 %bf.load, 8