[polly] r248781 - Codegen: Support memory accesses with different types

Tobias Grosser via llvm-commits llvm-commits at lists.llvm.org
Mon Sep 28 23:44:38 PDT 2015


Author: grosser
Date: Tue Sep 29 01:44:38 2015
New Revision: 248781

URL: http://llvm.org/viewvc/llvm-project?rev=248781&view=rev
Log:
Codegen: Support memory accesses with different types

Every once in a while we see code that accesses memory with different types,
e.g. to perform operations on a piece of memory using type 'float', but to copy
data to this memory using type 'int'. Modeled in C, such codes look like:

    void foo(float A[], float B[]) {
      for (long i = 0; i < 100; i++)
        *(int *)(&A[i]) = *(int *)(&B[i]);
      for (long i = 0; i < 100; i++)
        A[i] += 10;
    }

We already used the correct types during normal operations, but fall back to our
detected type as soon as we import changed memory access functions. For these
memory accesses we may generate invalid IR due to a mismatch between the element
type of the array we detect and the actual type used in the memory access.  To
address this issue, we always cast the newly created address of a memory access
back to the type of the memory access where the address will be used.

Added:
    polly/trunk/test/Isl/CodeGen/MemAccess/different_types.ll
    polly/trunk/test/Isl/CodeGen/MemAccess/different_types___%bb2---%bb18.jscop
Modified:
    polly/trunk/lib/CodeGen/BlockGenerators.cpp

Modified: polly/trunk/lib/CodeGen/BlockGenerators.cpp
URL: http://llvm.org/viewvc/llvm-project/polly/trunk/lib/CodeGen/BlockGenerators.cpp?rev=248781&r1=248780&r2=248781&view=diff
==============================================================================
--- polly/trunk/lib/CodeGen/BlockGenerators.cpp (original)
+++ polly/trunk/lib/CodeGen/BlockGenerators.cpp Tue Sep 29 01:44:38 2015
@@ -197,7 +197,23 @@ Value *BlockGenerator::generateLocationA
 
   if (AccessExpr) {
     AccessExpr = isl_ast_expr_address_of(AccessExpr);
-    return ExprBuilder->create(AccessExpr);
+    auto Address = ExprBuilder->create(AccessExpr);
+
+    // Cast the address of this memory access to a pointer type that has the
+    // same element type as the original access, but uses the address space of
+    // the newly generated pointer.
+    auto OldPtrTy = MA.getAccessValue()->getType()->getPointerTo();
+    auto NewPtrTy = Address->getType();
+    OldPtrTy = PointerType::get(OldPtrTy->getElementType(),
+                                NewPtrTy->getPointerAddressSpace());
+
+    if (OldPtrTy != NewPtrTy) {
+      assert(OldPtrTy->getPointerElementType()->getPrimitiveSizeInBits() ==
+                 NewPtrTy->getPointerElementType()->getPrimitiveSizeInBits() &&
+             "Pointer types to elements with different size found");
+      Address = Builder.CreateBitOrPointerCast(Address, OldPtrTy);
+    }
+    return Address;
   }
 
   return getNewValue(Stmt, Pointer, BBMap, LTS, getLoopForInst(Inst));

Added: polly/trunk/test/Isl/CodeGen/MemAccess/different_types.ll
URL: http://llvm.org/viewvc/llvm-project/polly/trunk/test/Isl/CodeGen/MemAccess/different_types.ll?rev=248781&view=auto
==============================================================================
--- polly/trunk/test/Isl/CodeGen/MemAccess/different_types.ll (added)
+++ polly/trunk/test/Isl/CodeGen/MemAccess/different_types.ll Tue Sep 29 01:44:38 2015
@@ -0,0 +1,63 @@
+; RUN: opt %loadPolly -polly-detect-unprofitable -polly-import-jscop \
+; RUN: -polly-import-jscop-dir=%S -polly-no-early-exit \
+; RUN: -polly-codegen -S < %s | FileCheck %s
+;
+;    void foo(float A[], float B[]) {
+;      for (long i = 0; i < 100; i++)
+;        *(int *)(&A[i]) = *(int *)(&B[i]);
+;      for (long i = 0; i < 100; i++)
+;        A[i] += 10;
+;    }
+
+; CHECK: %polly.access.cast.A14 = bitcast float* %A to i32*
+; CHECK: %5 = sub nsw i64 99, %polly.indvar11
+; CHECK: %polly.access.A15 = getelementptr i32, i32* %polly.access.cast.A14, i64 %5
+; CHECK: %6 = bitcast i32* %polly.access.A15 to float*
+; CHECK: %tmp14_p_scalar_ = load float, float* %6, align 4, !alias.scope !3, !noalias !4
+
+target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"
+
+define void @different_types(float* %A, float* %B) {
+bb:
+  br label %bb2
+
+bb2:                                              ; preds = %bb8, %bb
+  %i.0 = phi i64 [ 0, %bb ], [ %tmp9, %bb8 ]
+  %exitcond1 = icmp ne i64 %i.0, 100
+  br i1 %exitcond1, label %bb3, label %bb10
+
+bb3:                                              ; preds = %bb2
+  %tmp = getelementptr inbounds float, float* %B, i64 %i.0
+  %tmp4 = bitcast float* %tmp to i32*
+  %tmp5 = load i32, i32* %tmp4, align 4
+  %tmp6 = getelementptr inbounds float, float* %A, i64 %i.0
+  %tmp7 = bitcast float* %tmp6 to i32*
+  store i32 %tmp5, i32* %tmp7, align 4
+  br label %bb8
+
+bb8:                                              ; preds = %bb3
+  %tmp9 = add nuw nsw i64 %i.0, 1
+  br label %bb2
+
+bb10:                                             ; preds = %bb2
+  br label %bb11
+
+bb11:                                             ; preds = %bb16, %bb10
+  %i1.0 = phi i64 [ 0, %bb10 ], [ %tmp17, %bb16 ]
+  %exitcond = icmp ne i64 %i1.0, 100
+  br i1 %exitcond, label %bb12, label %bb18
+
+bb12:                                             ; preds = %bb11
+  %tmp13 = getelementptr inbounds float, float* %A, i64 %i1.0
+  %tmp14 = load float, float* %tmp13, align 4
+  %tmp15 = fadd float %tmp14, 1.000000e+01
+  store float %tmp15, float* %tmp13, align 4
+  br label %bb16
+
+bb16:                                             ; preds = %bb12
+  %tmp17 = add nuw nsw i64 %i1.0, 1
+  br label %bb11
+
+bb18:                                             ; preds = %bb11
+  ret void
+}

Added: polly/trunk/test/Isl/CodeGen/MemAccess/different_types___%bb2---%bb18.jscop
URL: http://llvm.org/viewvc/llvm-project/polly/trunk/test/Isl/CodeGen/MemAccess/different_types___%25bb2---%25bb18.jscop?rev=248781&view=auto
==============================================================================
--- polly/trunk/test/Isl/CodeGen/MemAccess/different_types___%bb2---%bb18.jscop (added)
+++ polly/trunk/test/Isl/CodeGen/MemAccess/different_types___%bb2---%bb18.jscop Tue Sep 29 01:44:38 2015
@@ -0,0 +1,36 @@
+{
+   "context" : "{  :  }",
+   "name" : "bb2 => bb18",
+   "statements" : [
+      {
+         "accesses" : [
+            {
+               "kind" : "read",
+               "relation" : "{ Stmt_bb3[i0] -> MemRef_B[i0] }"
+            },
+            {
+               "kind" : "write",
+               "relation" : "{ Stmt_bb3[i0] -> MemRef_A[99 - i0] }"
+            }
+         ],
+         "domain" : "{ Stmt_bb3[i0] : i0 <= 99 and i0 >= 0 }",
+         "name" : "Stmt_bb3",
+         "schedule" : "{ Stmt_bb3[i0] -> [0, i0] }"
+      },
+      {
+         "accesses" : [
+            {
+               "kind" : "read",
+               "relation" : "{ Stmt_bb12[i0] -> MemRef_A[99 - i0] }"
+            },
+            {
+               "kind" : "write",
+               "relation" : "{ Stmt_bb12[i0] -> MemRef_A[i0] }"
+            }
+         ],
+         "domain" : "{ Stmt_bb12[i0] : i0 <= 99 and i0 >= 0 }",
+         "name" : "Stmt_bb12",
+         "schedule" : "{ Stmt_bb12[i0] -> [1, i0] }"
+      }
+   ]
+}




More information about the llvm-commits mailing list