[PATCH] D54653: Correct CreateAlignmentAssumption to check sign and power-of-2 (LLVM Part)

Erich Keane via Phabricator via llvm-commits llvm-commits at lists.llvm.org
Fri Nov 16 14:59:30 PST 2018


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

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

(see test in clang commit)


Repository:
  rL LLVM

https://reviews.llvm.org/D54653

Files:
  include/llvm/IR/IRBuilder.h


Index: include/llvm/IR/IRBuilder.h
===================================================================
--- include/llvm/IR/IRBuilder.h
+++ include/llvm/IR/IRBuilder.h
@@ -54,6 +54,9 @@
 class MDNode;
 class Use;
 
+
+enum class AlignmentSign { Signed, Unsigned};
+
 /// This provides the default implementation of the IRBuilder
 /// 'InsertHelper' method that is called whenever an instruction is created by
 /// IRBuilder and needs to be inserted.
@@ -2182,22 +2185,37 @@
   /// This overload handles the condition where the Alignment is dependent
   /// on an existing value rather than a static value.
   CallInst *CreateAlignmentAssumption(const DataLayout &DL, Value *PtrValue,
-                                      Value *Alignment,
+                                      Value *Alignment, AlignmentSign Sign,
                                       Value *OffsetValue = nullptr) {
     assert(isa<PointerType>(PtrValue->getType()) &&
            "trying to create an alignment assumption on a non-pointer?");
     auto *PtrTy = cast<PointerType>(PtrValue->getType());
     Type *IntPtrTy = getIntPtrTy(DL, PtrTy->getAddressSpace());
 
     if (Alignment->getType() != IntPtrTy)
-      Alignment = CreateIntCast(Alignment, IntPtrTy, /*isSigned*/ true,
+      Alignment = CreateIntCast(Alignment, IntPtrTy,
+                                /*isSigned*/ Sign == AlignmentSign::Signed,
                                 "alignmentcast");
-    Value *IsPositive =
-        CreateICmp(CmpInst::ICMP_SGT, Alignment,
-                   ConstantInt::get(Alignment->getType(), 0), "ispositive");
-    Value *PositiveMask =
-        CreateSub(Alignment, ConstantInt::get(IntPtrTy, 1), "positivemask");
-    Value *Mask = CreateSelect(IsPositive, PositiveMask,
+
+    // Alignments are only valid if  > 0 && IsPowerOf2.
+    Value *IsPositive = CreateICmp(
+        Sign == AlignmentSign::Signed ? CmpInst::ICMP_SGT : CmpInst::ICMP_UGT,
+        Alignment, ConstantInt::get(Alignment->getType(), 0), "ispositive");
+
+    // Save alignment - 1, which is valuable for both IsPowerOf2 and creating
+    // the mask.
+    Value *Sub1 =
+        CreateSub(Alignment, ConstantInt::get(IntPtrTy, 1), "alignsubone");
+
+    // Calculate Alignment & (Alignment - 1) == 0
+    Value *AlignAndMinus1 = CreateAnd(Alignment, Sub1, "alignandsubone");
+    Value *IsPowerOf2 =
+        CreateICmpEQ(AlignAndMinus1, ConstantInt::get(Alignment->getType(), 0),
+                     "ispowertwo");
+
+    Value *ValidMask = CreateAnd(IsPositive, IsPowerOf2, "alignisvalid");
+
+    Value *Mask = CreateSelect(ValidMask, Sub1,
                                ConstantInt::get(IntPtrTy, 0), "mask");
 
     return CreateAlignmentAssumptionHelper(DL, PtrValue, Mask, IntPtrTy,


-------------- next part --------------
A non-text attachment was scrubbed...
Name: D54653.174459.patch
Type: text/x-patch
Size: 2752 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20181116/0ce24149/attachment.bin>


More information about the llvm-commits mailing list