erichkeane created this revision.
erichkeane added reviewers: jyknight, craig.topper, lebedev.ri.

As discussed on IRC, check sign/power of 2 correctly for the
alignment assumptions.


Repository:
  rC Clang

https://reviews.llvm.org/D54654

Files:
  lib/CodeGen/CGCall.cpp
  lib/CodeGen/CodeGenFunction.h
  test/CodeGen/alloc-align-attr.c

Index: test/CodeGen/alloc-align-attr.c
===================================================================
--- test/CodeGen/alloc-align-attr.c
+++ test/CodeGen/alloc-align-attr.c
@@ -8,9 +8,12 @@
   return *m1(a);
 // CHECK: call i32* @m1(i32 [[PARAM1:%[^\)]+]]) 
 // CHECK: [[ALIGNCAST1:%.+]] = sext i32 [[PARAM1]] to i64
-// CHECK: [[ISPOS1:%.+]] = icmp sgt i64 [[ALIGNCAST1]], 0
-// CHECK: [[POSMASK1:%.+]] = sub i64 [[ALIGNCAST1]], 1
-// CHECK: [[MASK1:%.+]] = select i1 [[ISPOS1]], i64 [[POSMASK1]], i64 0
+// CHECK: [[ISPOS:%.+]] = icmp sgt i64 [[ALIGNCAST1]], 0
+// CHECK: [[ALIGNSUB1:%.+]] = sub i64 [[ALIGNCAST1]], 1
+// CHECK: [[ALIGNANDSUB1:%.+]] = and i64 [[ALIGNCAST1]], [[ALIGNSUB1]]
+// CHECK: [[ISPOWER2:%.+]] = icmp eq i64 [[ALIGNANDSUB1]], 0
+// CHECK: [[ALIGNVALID:%.+]] = and i1 [[ISPOS]], [[ISPOWER2]]
+// CHECK: [[MASK1:%.+]] = select i1 [[ALIGNVALID]], i64 [[ALIGNSUB1]], i64 0
 // CHECK: [[PTRINT1:%.+]] = ptrtoint
 // CHECK: [[MASKEDPTR1:%.+]] = and i64 [[PTRINT1]], [[MASK1]]
 // CHECK: [[MASKCOND1:%.+]] = icmp eq i64 [[MASKEDPTR1]], 0
@@ -23,9 +26,12 @@
 // CHECK: [[CONV2:%.+]] = trunc i64 %{{.+}} to i32
 // CHECK: call i32* @m1(i32 [[CONV2]])
 // CHECK: [[ALIGNCAST2:%.+]] = sext i32 [[CONV2]] to i64
-// CHECK: [[ISPOS2:%.+]] = icmp sgt i64 [[ALIGNCAST2]], 0
-// CHECK: [[POSMASK2:%.+]] = sub i64 [[ALIGNCAST2]], 1
-// CHECK: [[MASK2:%.+]] = select i1 [[ISPOS2]], i64 [[POSMASK2]], i64 0
+// CHECK: [[ISPOS:%.+]] = icmp sgt i64 [[ALIGNCAST2]], 0
+// CHECK: [[ALIGNSUB1:%.+]] = sub i64 [[ALIGNCAST2]], 1
+// CHECK: [[ALIGNANDSUB1:%.+]] = and i64 [[ALIGNCAST2]], [[ALIGNSUB1]]
+// CHECK: [[ISPOWER2:%.+]] = icmp eq i64 [[ALIGNANDSUB1]], 0
+// CHECK: [[ALIGNVALID:%.+]] = and i1 [[ISPOS]], [[ISPOWER2]]
+// CHECK: [[MASK2:%.+]] = select i1 [[ALIGNVALID]], i64 [[ALIGNSUB1]], i64 0
 // CHECK: [[PTRINT2:%.+]] = ptrtoint
 // CHECK: [[MASKEDPTR2:%.+]] = and i64 [[PTRINT2]], [[MASK2]]
 // CHECK: [[MASKCOND2:%.+]] = icmp eq i64 [[MASKEDPTR2]], 0
@@ -39,9 +45,12 @@
   return *m2(a);
 // CHECK: [[CONV3:%.+]] = sext i32 %{{.+}} to i64
 // CHECK: call i32* @m2(i64 [[CONV3]])
-// CHECK: [[ISPOS3:%.+]] = icmp sgt i64 [[CONV3]], 0
-// CHECK: [[POSMASK3:%.+]] = sub i64 [[CONV3]], 1
-// CHECK: [[MASK3:%.+]] = select i1 [[ISPOS3]], i64 [[POSMASK3]], i64 0
+// CHECK: [[ISPOS:%.+]] = icmp ugt i64 [[CONV3]], 0
+// CHECK: [[ALIGNSUB1:%.+]] = sub i64 [[CONV3]], 1
+// CHECK: [[ALIGNANDSUB1:%.+]] = and i64 [[CONV3]], [[ALIGNSUB1]]
+// CHECK: [[ISPOWER2:%.+]] = icmp eq i64 [[ALIGNANDSUB1]], 0
+// CHECK: [[ALIGNVALID:%.+]] = and i1 [[ISPOS]], [[ISPOWER2]]
+// CHECK: [[MASK3:%.+]] = select i1 [[ALIGNVALID]], i64 [[ALIGNSUB1]], i64 0
 // CHECK: [[PTRINT3:%.+]] = ptrtoint
 // CHECK: [[MASKEDPTR3:%.+]] = and i64 [[PTRINT3]], [[MASK3]]
 // CHECK: [[MASKCOND3:%.+]] = icmp eq i64 [[MASKEDPTR3]], 0
@@ -53,16 +62,18 @@
 // CHECK: define i32 @test4
   return *m2(a);
 // CHECK: call i32* @m2(i64 [[PARAM4:%[^\)]+]]) 
-// CHECK: [[ISPOS4:%.+]] = icmp sgt i64 [[PARAM4]], 0
-// CHECK: [[POSMASK4:%.+]] = sub i64 [[PARAM4]], 1
-// CHECK: [[MASK4:%.+]] = select i1 [[ISPOS4]], i64 [[POSMASK4]], i64 0
+// CHECK: [[ISPOS:%.+]] = icmp ugt i64 [[PARAM4]], 0
+// CHECK: [[ALIGNSUB1:%.+]] = sub i64 [[PARAM4]], 1
+// CHECK: [[ALIGNANDSUB1:%.+]] = and i64 [[PARAM4]], [[ALIGNSUB1]]
+// CHECK: [[ISPOWER2:%.+]] = icmp eq i64 [[ALIGNANDSUB1]], 0
+// CHECK: [[ALIGNVALID:%.+]] = and i1 [[ISPOS]], [[ISPOWER2]]
+// CHECK: [[MASK4:%.+]] = select i1 [[ALIGNVALID]], i64 [[ALIGNSUB1]], i64 0
 // CHECK: [[PTRINT4:%.+]] = ptrtoint
 // CHECK: [[MASKEDPTR4:%.+]] = and i64 [[PTRINT4]], [[MASK4]]
 // CHECK: [[MASKCOND4:%.+]] = icmp eq i64 [[MASKEDPTR4]], 0
 // CHECK: call void @llvm.assume(i1 [[MASKCOND4]])
 }
 
-
 struct Empty {};
 struct MultiArgs { __INT64_TYPE__ a, b;};
 // Struct parameter doesn't take up an IR parameter, 'i' takes up 2.
@@ -74,9 +85,12 @@
   return *m3(e, a);
 // CHECK: call i32* @m3(i64 %{{.*}}, i64 %{{.*}}) 
 // CHECK: [[ALIGNCAST5:%.+]] = trunc i128 %{{.*}} to i64
-// CHECK: [[ISPOS5:%.+]] = icmp sgt i64 [[ALIGNCAST5]], 0
-// CHECK: [[POSMASK5:%.+]] = sub i64 [[ALIGNCAST5]], 1
-// CHECK: [[MASK5:%.+]] = select i1 [[ISPOS5]], i64 [[POSMASK5]], i64 0
+// CHECK: [[ISPOS:%.+]] = icmp sgt i64 [[ALIGNCAST5]], 0
+// CHECK: [[ALIGNSUB1:%.+]] = sub i64 [[ALIGNCAST5]], 1
+// CHECK: [[ALIGNANDSUB1:%.+]] = and i64 [[ALIGNCAST5]], [[ALIGNSUB1]]
+// CHECK: [[ISPOWER2:%.+]] = icmp eq i64 [[ALIGNANDSUB1]], 0
+// CHECK: [[ALIGNVALID:%.+]] = and i1 [[ISPOS]], [[ISPOWER2]]
+// CHECK: [[MASK5:%.+]] = select i1 [[ALIGNVALID]], i64 [[ALIGNSUB1]], i64 0
 // CHECK: [[PTRINT5:%.+]] = ptrtoint
 // CHECK: [[MASKEDPTR5:%.+]] = and i64 [[PTRINT5]], [[MASK5]]
 // CHECK: [[MASKCOND5:%.+]] = icmp eq i64 [[MASKEDPTR5]], 0
@@ -90,9 +104,12 @@
   return *m4(e, a);
 // CHECK: call i32* @m4(i64 %{{.*}}, i64 %{{.*}}, i64 %{{.*}}) 
 // CHECK: [[ALIGNCAST6:%.+]] = trunc i128 %{{.*}} to i64
-// CHECK: [[ISPOS6:%.+]] = icmp sgt i64 [[ALIGNCAST6]], 0
-// CHECK: [[POSMASK6:%.+]] = sub i64 [[ALIGNCAST6]], 1
-// CHECK: [[MASK6:%.+]] = select i1 [[ISPOS6]], i64 [[POSMASK6]], i64 0
+// CHECK: [[ISPOS:%.+]] = icmp sgt i64 [[ALIGNCAST6]], 0
+// CHECK: [[ALIGNSUB1:%.+]] = sub i64 [[ALIGNCAST6]], 1
+// CHECK: [[ALIGNANDSUB1:%.+]] = and i64 [[ALIGNCAST6]], [[ALIGNSUB1]]
+// CHECK: [[ISPOWER2:%.+]] = icmp eq i64 [[ALIGNANDSUB1]], 0
+// CHECK: [[ALIGNVALID:%.+]] = and i1 [[ISPOS]], [[ISPOWER2]]
+// CHECK: [[MASK6:%.+]] = select i1 [[ALIGNVALID]], i64 [[ALIGNSUB1]], i64 0
 // CHECK: [[PTRINT6:%.+]] = ptrtoint
 // CHECK: [[MASKEDPTR6:%.+]] = and i64 [[PTRINT6]], [[MASK6]]
 // CHECK: [[MASKCOND6:%.+]] = icmp eq i64 [[MASKEDPTR6]], 0
Index: lib/CodeGen/CodeGenFunction.h
===================================================================
--- lib/CodeGen/CodeGenFunction.h
+++ lib/CodeGen/CodeGenFunction.h
@@ -2803,9 +2803,16 @@
   void unprotectFromPeepholes(PeepholeProtection protection);
 
   void EmitAlignmentAssumption(llvm::Value *PtrValue, llvm::Value *Alignment,
+                               const clang::Type &AlignmentType,
                                llvm::Value *OffsetValue = nullptr) {
-    Builder.CreateAlignmentAssumption(CGM.getDataLayout(), PtrValue, Alignment,
-                                      OffsetValue);
+    assert(AlignmentType.isIntegralOrUnscopedEnumerationType() &&
+           "Alignment can only be an integer type");
+    Builder.CreateAlignmentAssumption(
+        CGM.getDataLayout(), PtrValue, Alignment,
+        AlignmentType.isSignedIntegerOrEnumerationType()
+            ? llvm::AlignmentSign::Signed
+            : llvm::AlignmentSign::Unsigned,
+        OffsetValue);
   }
 
   //===--------------------------------------------------------------------===//
Index: lib/CodeGen/CGCall.cpp
===================================================================
--- lib/CodeGen/CGCall.cpp
+++ lib/CodeGen/CGCall.cpp
@@ -4508,10 +4508,9 @@
       EmitAlignmentAssumption(Ret.getScalarVal(), AlignmentCI->getZExtValue(),
                               OffsetValue);
     } else if (const auto *AA = TargetDecl->getAttr<AllocAlignAttr>()) {
-      llvm::Value *ParamVal =
-          CallArgs[AA->getParamIndex().getLLVMIndex()].getRValue(
-              *this).getScalarVal();
-      EmitAlignmentAssumption(Ret.getScalarVal(), ParamVal);
+      CallArg Arg = CallArgs[AA->getParamIndex().getLLVMIndex()];
+      llvm::Value *ParamVal = Arg.getRValue(*this).getScalarVal();
+      EmitAlignmentAssumption(Ret.getScalarVal(), ParamVal, *Arg.getType());
     }
   }
 
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to