[PATCH] Propagate instruction metadata during SLP vectorization.

Raul Silvera rsilvera at google.com
Fri Nov 15 13:20:20 PST 2013


rsilvera added you to the CC list for the revision "Propagate instruction metadata during SLP vectorization.".

Hi hfinkel, nadav,

Migrate metadata information from scalar to vector instructions
durign SLP vectorization. Most of the code is lifted from BBVectorizer.cpp

http://llvm-reviews.chandlerc.com/D2191

Files:
  lib/Transforms/Vectorize/SLPVectorizer.cpp
  test/Transforms/SLPVectorizer/X86/metadata.ll

Index: lib/Transforms/Vectorize/SLPVectorizer.cpp
===================================================================
--- lib/Transforms/Vectorize/SLPVectorizer.cpp
+++ lib/Transforms/Vectorize/SLPVectorizer.cpp
@@ -163,6 +163,39 @@
   return Opcode;
 }
 
+/// \returns \p I after propagating metadata from \p VL.
+static Instruction *propagateMetadata(Instruction *I, ArrayRef<Value *> VL) {
+  Instruction *I0 = dyn_cast<Instruction>(VL[0]);
+  if (!I0) return I;
+
+  SmallVector<std::pair<unsigned, MDNode*>, 4> Metadata;
+  I0->getAllMetadataOtherThanDebugLoc(Metadata);
+
+  for (unsigned i = 0, n = Metadata.size(); i < n; ++i) {
+    unsigned Kind = Metadata[i].first;
+    MDNode *MD = Metadata[i].second;
+
+    for (int i = 1, e = VL.size(); MD && i < e; i++) {
+      Instruction *I = dyn_cast<Instruction>(VL[i]);
+      MDNode *IMD = I->getMetadata(Kind);
+
+      switch(Kind) {
+        default:
+          MD = 0; // Remove unknown metadata
+          break;
+        case LLVMContext::MD_tbaa:
+          MD = MDNode::getMostGenericTBAA(MD, IMD);
+          break;
+        case LLVMContext::MD_fpmath:
+          MD = MDNode::getMostGenericFPMath(MD, IMD);
+          break;
+      }
+    }
+    I->setMetadata(Kind, MD);
+  }
+  return I;
+}
+
 /// \returns The type that all of the values in \p VL have or null if there
 /// are different types.
 static Type* getSameType(ArrayRef<Value *> VL) {
@@ -1478,7 +1511,12 @@
       BinaryOperator *BinOp = cast<BinaryOperator>(VL0);
       Value *V = Builder.CreateBinOp(BinOp->getOpcode(), LHS, RHS);
       E->VectorizedValue = V;
-      return V;
+
+      const Instruction *I = dyn_cast<Instruction>(V);
+      if (!I)
+        return V;
+
+      return propagateMetadata(dyn_cast<Instruction>(V), E->Scalars);
     }
     case Instruction::Load: {
       // Loads are inserted at the head of the tree because we don't want to
@@ -1494,7 +1532,7 @@
       LI = Builder.CreateLoad(VecPtr);
       LI->setAlignment(Alignment);
       E->VectorizedValue = LI;
-      return LI;
+      return propagateMetadata(LI, E->Scalars);
     }
     case Instruction::Store: {
       StoreInst *SI = cast<StoreInst>(VL0);
@@ -1513,7 +1551,7 @@
       StoreInst *S = Builder.CreateStore(VecValue, VecPtr);
       S->setAlignment(Alignment);
       E->VectorizedValue = S;
-      return S;
+      return propagateMetadata(S, E->Scalars);
     }
     default:
     llvm_unreachable("unknown inst");
Index: test/Transforms/SLPVectorizer/X86/metadata.ll
===================================================================
--- /dev/null
+++ test/Transforms/SLPVectorizer/X86/metadata.ll
@@ -0,0 +1,59 @@
+; RUN: opt < %s -basicaa -slp-vectorizer -dce -S -mtriple=x86_64-apple-macosx10.8.0 -mcpu=corei7-avx | FileCheck %s
+
+target datalayout = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128-n8:16:32:64-S128"
+target triple = "x86_64-apple-macosx10.8.0"
+;CHECK: test1
+;CHECK: load <2 x double>{{.*}}!tbaa ![[TBAA:[0-9]+]]
+;CHECK: load <2 x double>{{.*}}!tbaa ![[TBAA]]
+;CHECK: fmul <2 x double>{{.*}}!fpmath ![[FP1:[0-9]+]]
+;CHECK: store <2 x double>{{.*}}!tbaa ![[TBAA]]
+;CHECK: ret void
+define void @test1(double* %a, double* %b, double* %c) {
+entry:
+  %i0 = load double* %a, align 8, !tbaa !4
+  %i1 = load double* %b, align 8, !tbaa !4
+  %mul = fmul double %i0, %i1, !fpmath !0
+  %arrayidx3 = getelementptr inbounds double* %a, i64 1
+  %i3 = load double* %arrayidx3, align 8, !tbaa !4
+  %arrayidx4 = getelementptr inbounds double* %b, i64 1
+  %i4 = load double* %arrayidx4, align 8, !tbaa !4
+  %mul5 = fmul double %i3, %i4, !fpmath !0
+  store double %mul, double* %c, align 8, !tbaa !4
+  %arrayidx5 = getelementptr inbounds double* %c, i64 1
+  store double %mul5, double* %arrayidx5, align 8, !tbaa !4
+  ret void
+}
+
+;CHECK: test2
+;CHECK: load <2 x double>{{.*}}!tbaa ![[TBAA]]
+;CHECK: load <2 x double>{{.*}}!tbaa ![[TBAA]]
+;CHECK: fmul <2 x double>{{.*}}!fpmath ![[FP2:[0-9]+]]
+;CHECK: store <2 x double>{{.*}}!tbaa ![[TBAA]]
+;CHECK: ret void
+
+define void @test2(double* %a, double* %b, i8* %e) {
+entry:
+  %i0 = load double* %a, align 8, !tbaa !4
+  %i1 = load double* %b, align 8, !tbaa !4
+  %mul = fmul double %i0, %i1, !fpmath !1
+  %arrayidx3 = getelementptr inbounds double* %a, i64 1
+  %i3 = load double* %arrayidx3, align 8, !tbaa !4
+  %arrayidx4 = getelementptr inbounds double* %b, i64 1
+  %i4 = load double* %arrayidx4, align 8, !tbaa !4
+  %mul5 = fmul double %i3, %i4, !fpmath !1
+  %c = bitcast i8* %e to double*
+  store double %mul, double* %c, align 8, !tbaa !4
+  %carrayidx5 = getelementptr inbounds i8* %e, i64 8
+  %arrayidx5 = bitcast i8* %carrayidx5 to double*
+  store double %mul5, double* %arrayidx5, align 8, !tbaa !4
+  ret void
+}
+
+;CHECK-DAG: ![[TBAA]] = metadata !{metadata [[TYPEC:!.*]], metadata [[TYPEC]], i64 0}
+;CHECK-DAG: ![[FP1]] = metadata !{float 5.000000e+00}
+;CHECK-DAG: ![[FP2]] = metadata !{float 2.500000e+00}
+!0 = metadata !{ float 5.0 }
+!1 = metadata !{ float 2.5 }
+!2 = metadata !{metadata !"Simple C/C++ TBAA"}
+!3 = metadata !{metadata !"omnipotent char", metadata !2}
+!4 = metadata !{metadata !"double", metadata !3}
-------------- next part --------------
A non-text attachment was scrubbed...
Name: D2191.1.patch
Type: text/x-patch
Size: 5247 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20131115/1ecd4d25/attachment.bin>


More information about the llvm-commits mailing list