From: Chris Lattner Date: Fri, 5 Mar 2010 18:53:28 +0000 (+0000) Subject: fix PR6512, a case where instcombine would incorrectly merge loads X-Git-Url: http://demsky.eecs.uci.edu/git/?a=commitdiff_plain;h=4c5fb1a311a7a5e3ceb802f5b26329d30f2713b1;p=oota-llvm.git fix PR6512, a case where instcombine would incorrectly merge loads from different addr spaces. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@97813 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/lib/Transforms/InstCombine/InstCombinePHI.cpp b/lib/Transforms/InstCombine/InstCombinePHI.cpp index fba83542cdb..65f03936870 100644 --- a/lib/Transforms/InstCombine/InstCombinePHI.cpp +++ b/lib/Transforms/InstCombine/InstCombinePHI.cpp @@ -266,6 +266,7 @@ Instruction *InstCombiner::FoldPHIArgLoadIntoPHI(PHINode &PN) { // and if TD isn't around, we can't handle the mixed case. bool isVolatile = FirstLI->isVolatile(); unsigned LoadAlignment = FirstLI->getAlignment(); + unsigned LoadAddrSpace = FirstLI->getPointerAddressSpace(); // We can't sink the load if the loaded value could be modified between the // load and the PHI. @@ -290,6 +291,7 @@ Instruction *InstCombiner::FoldPHIArgLoadIntoPHI(PHINode &PN) { // the load and the PHI. if (LI->isVolatile() != isVolatile || LI->getParent() != PN.getIncomingBlock(i) || + LI->getPointerAddressSpace() != LoadAddrSpace || !isSafeAndProfitableToSinkLoad(LI)) return 0; diff --git a/test/Transforms/InstCombine/phi.ll b/test/Transforms/InstCombine/phi.ll index f0343e44c2b..fc321e96822 100644 --- a/test/Transforms/InstCombine/phi.ll +++ b/test/Transforms/InstCombine/phi.ll @@ -362,3 +362,43 @@ end: ; CHECK-NEXT: ret i64 } +; PR6512 - Shouldn't merge loads from different addr spaces. +define i32 @test16(i32 addrspace(1)* %pointer1, i32 %flag, i32* %pointer2) +nounwind { +entry: + %retval = alloca i32, align 4 ; [#uses=2] + %pointer1.addr = alloca i32 addrspace(1)*, align 4 ; + %flag.addr = alloca i32, align 4 ; [#uses=2] + %pointer2.addr = alloca i32*, align 4 ; [#uses=2] + %res = alloca i32, align 4 ; [#uses=4] + store i32 addrspace(1)* %pointer1, i32 addrspace(1)** %pointer1.addr + store i32 %flag, i32* %flag.addr + store i32* %pointer2, i32** %pointer2.addr + store i32 10, i32* %res + %tmp = load i32* %flag.addr ; [#uses=1] + %tobool = icmp ne i32 %tmp, 0 ; [#uses=1] + br i1 %tobool, label %if.then, label %if.else + +return: ; preds = %if.end + %tmp7 = load i32* %retval ; [#uses=1] + ret i32 %tmp7 + +if.end: ; preds = %if.else, %if.then + %tmp6 = load i32* %res ; [#uses=1] + store i32 %tmp6, i32* %retval + br label %return + +if.then: ; preds = %entry + %tmp1 = load i32 addrspace(1)** %pointer1.addr ; + %arrayidx = getelementptr i32 addrspace(1)* %tmp1, i32 0 ; [#uses=1] + %tmp2 = load i32 addrspace(1)* %arrayidx ; [#uses=1] + store i32 %tmp2, i32* %res + br label %if.end + +if.else: ; preds = %entry + %tmp3 = load i32** %pointer2.addr ; [#uses=1] + %arrayidx4 = getelementptr i32* %tmp3, i32 0 ; [#uses=1] + %tmp5 = load i32* %arrayidx4 ; [#uses=1] + store i32 %tmp5, i32* %res + br label %if.end +}