[llvm] r351582 - [CGP] Check for existing inttotpr before creating new one

Roman Tereshin via llvm-commits llvm-commits at lists.llvm.org
Fri Jan 18 12:13:42 PST 2019


Author: rtereshin
Date: Fri Jan 18 12:13:42 2019
New Revision: 351582

URL: http://llvm.org/viewvc/llvm-project?rev=351582&view=rev
Log:
[CGP] Check for existing inttotpr before creating new one

Make sure CodeGenPrepare doesn't emit multiple inttoptr instructions of
the same integer value while sinking address computations, but rather
CSEs them on the fly: excessive inttoptr's confuse SCEV into thinking
that related pointers have nothing to do with each other.

This problem blocks LoadStoreVectorizer from vectorizing some of the
loads / stores in a downstream target.

Reviewed By: hfinkel

Differential Revision: https://reviews.llvm.org/D56838

Added:
    llvm/trunk/test/Transforms/CodeGenPrepare/X86/sink-addrmode-cse-inttoptrs.ll
Modified:
    llvm/trunk/lib/CodeGen/CodeGenPrepare.cpp

Modified: llvm/trunk/lib/CodeGen/CodeGenPrepare.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/CodeGenPrepare.cpp?rev=351582&r1=351581&r2=351582&view=diff
==============================================================================
--- llvm/trunk/lib/CodeGen/CodeGenPrepare.cpp (original)
+++ llvm/trunk/lib/CodeGen/CodeGenPrepare.cpp Fri Jan 18 12:13:42 2019
@@ -4664,13 +4664,22 @@ bool CodeGenPrepare::optimizeMemoryInst(
     // will look through it and provide only the integer value. In that case,
     // use it here.
     if (!DL->isNonIntegralPointerType(Addr->getType())) {
+      const auto getResultPtr = [MemoryInst, Addr,
+                                 &Builder](Value *Reg) -> Value * {
+        for (User *U : Reg->users())
+          if (auto *I2P = dyn_cast<IntToPtrInst>(U))
+            if (I2P->getType() == Addr->getType() &&
+                I2P->getParent() == MemoryInst->getParent()) {
+              I2P->moveBefore(MemoryInst->getParent()->getFirstNonPHI());
+              return I2P;
+            }
+        return Builder.CreateIntToPtr(Reg, Addr->getType(), "sunkaddr");
+      };
       if (!ResultPtr && AddrMode.BaseReg) {
-        ResultPtr = Builder.CreateIntToPtr(AddrMode.BaseReg, Addr->getType(),
-                                           "sunkaddr");
+        ResultPtr = getResultPtr(AddrMode.BaseReg);
         AddrMode.BaseReg = nullptr;
       } else if (!ResultPtr && AddrMode.Scale == 1) {
-        ResultPtr = Builder.CreateIntToPtr(AddrMode.ScaledReg, Addr->getType(),
-                                           "sunkaddr");
+        ResultPtr = getResultPtr(AddrMode.ScaledReg);
         AddrMode.Scale = 0;
       }
     }

Added: llvm/trunk/test/Transforms/CodeGenPrepare/X86/sink-addrmode-cse-inttoptrs.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Transforms/CodeGenPrepare/X86/sink-addrmode-cse-inttoptrs.ll?rev=351582&view=auto
==============================================================================
--- llvm/trunk/test/Transforms/CodeGenPrepare/X86/sink-addrmode-cse-inttoptrs.ll (added)
+++ llvm/trunk/test/Transforms/CodeGenPrepare/X86/sink-addrmode-cse-inttoptrs.ll Fri Jan 18 12:13:42 2019
@@ -0,0 +1,40 @@
+; RUN: opt -mtriple=x86_64-- -codegenprepare                        %s -S -o - | FileCheck %s --check-prefix=CGP
+; RUN: opt -mtriple=x86_64-- -codegenprepare -load-store-vectorizer %s -S -o - | FileCheck %s --check-prefix=LSV
+
+; Make sure CodeGenPrepare doesn't emit multiple inttoptr instructions
+; of the same integer value while sinking address computations, but
+; rather CSEs them on the fly: excessive inttoptr's confuse SCEV
+; into thinking that related pointers have nothing to do with each other.
+;
+; Triggering this problem involves having just right addressing modes,
+; and verifying that the motivating pass (LoadStoreVectorizer) is able
+; to benefit from it - just right LSV-policies. Hence the atypical combination
+; of the target and datalayout / address spaces in this test.
+
+target datalayout = "p1:32:32:32"
+
+define void @main(i32 %tmp, i32 %off) {
+; CGP:     = inttoptr
+; CGP-NOT: = inttoptr
+; LSV:     = load <2 x float>
+; LSV:     = load <2 x float>
+entry:
+  %tmp1 = inttoptr i32 %tmp to float addrspace(1)*
+  %arrayidx.i.7 = getelementptr inbounds float, float addrspace(1)* %tmp1, i32 %off
+  %add20.i.7 = add i32 %off, 1
+  %arrayidx22.i.7 = getelementptr inbounds float, float addrspace(1)* %tmp1, i32 %add20.i.7
+  br label %for.body
+
+for.body:
+  %tmp8 = phi float [ undef, %entry ], [ %tmp62, %for.body ]
+  %tmp28 = load float, float addrspace(1)* %arrayidx.i.7
+  %tmp29 = load float, float addrspace(1)* %arrayidx22.i.7
+  %arrayidx.i321.7 = getelementptr inbounds float, float addrspace(1)* %tmp1, i32 0
+  %tmp43 = load float, float addrspace(1)* %arrayidx.i321.7
+  %arrayidx22.i327.7 = getelementptr inbounds float, float addrspace(1)* %tmp1, i32 1
+  %tmp44 = load float, float addrspace(1)* %arrayidx22.i327.7
+  %tmp62 = tail call fast float @foo(float %tmp8, float %tmp44, float %tmp43, float %tmp29, float %tmp28)
+  br label %for.body
+}
+
+declare float @foo(float, float, float, float, float)




More information about the llvm-commits mailing list