]> granicus.if.org Git - clang/commitdiff
Preserve alignment for Neon vld1_lane/dup and vst1_lane intrinsics.
authorBob Wilson <bob.wilson@apple.com>
Sat, 4 Feb 2012 23:58:08 +0000 (23:58 +0000)
committerBob Wilson <bob.wilson@apple.com>
Sat, 4 Feb 2012 23:58:08 +0000 (23:58 +0000)
We had been generating load/store instructions with the default alignment
for the vector element type, even when the pointer argument had less alignment.
<rdar://problem/10538555>

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@149794 91177308-0d34-0410-b5e6-96231b3b80d8

lib/CodeGen/CGBuiltin.cpp
test/CodeGen/arm-vector-align.c

index e463230b978ade36c59e854bc9523fc9c44ffe2c..c4197e68701510ea43e0127318fe138530689074 100644 (file)
@@ -1516,20 +1516,25 @@ Value *CodeGenFunction::EmitARMBuiltinExpr(unsigned BuiltinID,
     return EmitNeonCall(CGM.getIntrinsic(Intrinsic::arm_neon_vld1, Ty),
                         Ops, "vld1");
   case ARM::BI__builtin_neon_vld1_lane_v:
-  case ARM::BI__builtin_neon_vld1q_lane_v:
+  case ARM::BI__builtin_neon_vld1q_lane_v: {
     Ops[1] = Builder.CreateBitCast(Ops[1], Ty);
     Ty = llvm::PointerType::getUnqual(VTy->getElementType());
     Ops[0] = Builder.CreateBitCast(Ops[0], Ty);
-    Ops[0] = Builder.CreateLoad(Ops[0]);
-    return Builder.CreateInsertElement(Ops[1], Ops[0], Ops[2], "vld1_lane");
+    LoadInst *Ld = Builder.CreateLoad(Ops[0]);
+    Value *Align = GetPointeeAlignment(*this, E->getArg(0));
+    Ld->setAlignment(cast<ConstantInt>(Align)->getZExtValue());
+    return Builder.CreateInsertElement(Ops[1], Ld, Ops[2], "vld1_lane");
+  }
   case ARM::BI__builtin_neon_vld1_dup_v:
   case ARM::BI__builtin_neon_vld1q_dup_v: {
     Value *V = UndefValue::get(Ty);
     Ty = llvm::PointerType::getUnqual(VTy->getElementType());
     Ops[0] = Builder.CreateBitCast(Ops[0], Ty);
-    Ops[0] = Builder.CreateLoad(Ops[0]);
+    LoadInst *Ld = Builder.CreateLoad(Ops[0]);
+    Value *Align = GetPointeeAlignment(*this, E->getArg(0));
+    Ld->setAlignment(cast<ConstantInt>(Align)->getZExtValue());
     llvm::Constant *CI = ConstantInt::get(Int32Ty, 0);
-    Ops[0] = Builder.CreateInsertElement(V, Ops[0], CI);
+    Ops[0] = Builder.CreateInsertElement(V, Ld, CI);
     return EmitNeonSplat(Ops[0], CI);
   }
   case ARM::BI__builtin_neon_vld2_v:
@@ -1877,11 +1882,16 @@ Value *CodeGenFunction::EmitARMBuiltinExpr(unsigned BuiltinID,
     return EmitNeonCall(CGM.getIntrinsic(Intrinsic::arm_neon_vst1, Ty),
                         Ops, "");
   case ARM::BI__builtin_neon_vst1_lane_v:
-  case ARM::BI__builtin_neon_vst1q_lane_v:
+  case ARM::BI__builtin_neon_vst1q_lane_v: {
     Ops[1] = Builder.CreateBitCast(Ops[1], Ty);
     Ops[1] = Builder.CreateExtractElement(Ops[1], Ops[2]);
     Ty = llvm::PointerType::getUnqual(Ops[1]->getType());
-    return Builder.CreateStore(Ops[1], Builder.CreateBitCast(Ops[0], Ty));
+    StoreInst *St = Builder.CreateStore(Ops[1],
+                                        Builder.CreateBitCast(Ops[0], Ty));
+    Value *Align = GetPointeeAlignment(*this, E->getArg(0));
+    St->setAlignment(cast<ConstantInt>(Align)->getZExtValue());
+    return St;
+  }
   case ARM::BI__builtin_neon_vst2_v:
   case ARM::BI__builtin_neon_vst2q_v:
     Ops.push_back(GetPointeeAlignment(*this, E->getArg(0)));
index c1119cb5b736e5af7b6905cb7742655ada7fb981..b481a0c97f8f627821a39ff387a44bd87f4d601d 100644 (file)
 // intrinsics.
 typedef float AlignedAddr __attribute__ ((aligned (16)));
 void t1(AlignedAddr *addr1, AlignedAddr *addr2) {
+// CHECK: @t1
 // CHECK: call <4 x float> @llvm.arm.neon.vld1.v4f32(i8* %{{.*}}, i32 16)
   float32x4_t a = vld1q_f32(addr1);
 // CHECK: call void @llvm.arm.neon.vst1.v4f32(i8* %{{.*}}, <4 x float> %{{.*}}, i32 16)
   vst1q_f32(addr2, a);
 }
+
+// Radar 10538555: Make sure unaligned load/stores do not gain alignment.
+void t2(char *addr) {
+// CHECK: @t2
+// CHECK: load i32* %{{.*}}, align 1
+  int32x2_t vec = vld1_dup_s32(addr);
+// CHECK: store i32 %{{.*}}, i32* {{.*}}, align 1
+  vst1_lane_s32(addr, vec, 1);
+}