<div dir="ltr"><br><div class="gmail_extra"><br><div class="gmail_quote">On Sun, Sep 7, 2014 at 3:58 PM, Hal Finkel <span dir="ltr"><<a href="mailto:hfinkel@anl.gov" target="_blank">hfinkel@anl.gov</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">Author: hfinkel<br>
Date: Sun Sep  7 17:58:14 2014<br>
New Revision: 217349<br>
<br>
URL: <a href="http://llvm.org/viewvc/llvm-project?rev=217349&view=rev" target="_blank">http://llvm.org/viewvc/llvm-project?rev=217349&view=rev</a><br>
Log:<br>
Add __builtin_assume and __builtin_assume_aligned using @llvm.assume.<br>
<br>
This makes use of the recently-added @llvm.assume intrinsic to implement a<br>
__builtin_assume(bool) intrinsic (to provide additional information to the<br>
optimizer). This hooks up __assume in MS-compatibility mode to mirror<br>
__builtin_assume (the semantics have been intentionally kept compatible), and<br>
implements GCC's __builtin_assume_aligned as assume((p - o) & mask == 0). LLVM<br>
now contains special logic to deal with assumptions of this form.<br>
<br>
Added:<br>
    cfe/trunk/test/CodeGen/builtin-assume-aligned.c<br>
    cfe/trunk/test/Sema/builtin-assume-aligned.c<br>
    cfe/trunk/test/SemaCXX/builtin-assume-aligned-tmpl.cpp<br>
Modified:<br>
    cfe/trunk/docs/LanguageExtensions.rst<br>
    cfe/trunk/include/clang/Basic/Builtins.def<br>
    cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td<br>
    cfe/trunk/include/clang/Sema/Sema.h<br>
    cfe/trunk/lib/AST/ExprConstant.cpp<br>
    cfe/trunk/lib/CodeGen/CGBuiltin.cpp<br>
    cfe/trunk/lib/CodeGen/CGExpr.cpp<br>
    cfe/trunk/lib/CodeGen/CodeGenFunction.h<br>
    cfe/trunk/lib/Sema/SemaChecking.cpp<br>
    cfe/trunk/lib/Sema/SemaDeclAttr.cpp<br>
    cfe/trunk/test/CodeGen/builtin-assume.c<br>
    cfe/trunk/test/Sema/builtin-assume.c<br>
<br>
Modified: cfe/trunk/docs/LanguageExtensions.rst<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/docs/LanguageExtensions.rst?rev=217349&r1=217348&r2=217349&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/docs/LanguageExtensions.rst?rev=217349&r1=217348&r2=217349&view=diff</a><br>
==============================================================================<br>
--- cfe/trunk/docs/LanguageExtensions.rst (original)<br>
+++ cfe/trunk/docs/LanguageExtensions.rst Sun Sep  7 17:58:14 2014<br>
@@ -1228,8 +1228,9 @@ Builtin Functions<br>
 Clang supports a number of builtin library functions with the same syntax as<br>
 GCC, including things like ``__builtin_nan``, ``__builtin_constant_p``,<br>
 ``__builtin_choose_expr``, ``__builtin_types_compatible_p``,<br>
-``__sync_fetch_and_add``, etc.  In addition to the GCC builtins, Clang supports<br>
-a number of builtins that GCC does not, which are listed here.<br>
+``__builtin_assume_aligned``, ``__sync_fetch_and_add``, etc.  In addition to<br>
+the GCC builtins, Clang supports a number of builtins that GCC does not, which<br>
+are listed here.<br>
<br>
 Please note that Clang does not and will not support all of the GCC builtins<br>
 for vector operations.  Instead of using builtins, you should use the functions<br>
@@ -1239,6 +1240,42 @@ implemented directly in terms of :ref:`e<br>
 <langext-vectors>` instead of builtins, in order to reduce the number of<br>
 builtins that we need to implement.<br>
<br>
+``__builtin_assume``<br>
+------------------------------<br>
+<br>
+``__builtin_assume`` is used to provide the optimizer with a boolean<br>
+invariant that is defined to be true.<br>
+<br>
+**Syntax**:<br>
+<br>
+.. code-block:: c++<br>
+<br>
+  __builtin_assume(bool)<br>
+<br>
+**Example of Use**:<br>
+<br>
+.. code-block:: c++<br>
+<br>
+  int foo(int x) {<br>
+    __builtin_assume(x != 0);<br>
+<br>
+    // The optimizer may short-circuit this check using the invariant.<br>
+    if (x == 0)<br>
+      return do_something();<br>
+<br>
+    return do_something_else();<br>
+  }<br>
+<br>
+**Description**:<br>
+<br>
+The boolean argument to this function is defined to be true. The optimizer may<br>
+analyze the form of the expression provided as the argument and deduce from<br>
+that information used to optimize the program. If the condition is violated<br>
+during execution, the behavior is undefined. The argument itself is never<br>
+evaluated, so any side effects of the expression will be discarded.<br>
+<br>
+Query for this feature with ``__has_builtin(__builtin_assume)``.<br>
+<br>
 ``__builtin_readcyclecounter``<br>
 ------------------------------<br>
<br>
<br>
Modified: cfe/trunk/include/clang/Basic/Builtins.def<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/Builtins.def?rev=217349&r1=217348&r2=217349&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/Builtins.def?rev=217349&r1=217348&r2=217349&view=diff</a><br>
==============================================================================<br>
--- cfe/trunk/include/clang/Basic/Builtins.def (original)<br>
+++ cfe/trunk/include/clang/Basic/Builtins.def Sun Sep  7 17:58:14 2014<br>
@@ -412,6 +412,7 @@ BUILTIN(__builtin_va_start, "vA.", "nt")<br>
 BUILTIN(__builtin_va_end, "vA", "n")<br>
 BUILTIN(__builtin_va_copy, "vAA", "n")<br>
 BUILTIN(__builtin_stdarg_start, "vA.", "n")<br>
+BUILTIN(__builtin_assume_aligned, "v*vC*z.", "nc")<br>
 BUILTIN(__builtin_bcmp, "iv*v*z", "n")<br>
 BUILTIN(__builtin_bcopy, "vv*v*z", "n")<br>
 BUILTIN(__builtin_bzero, "vv*z", "nF")<br>
@@ -1173,6 +1174,9 @@ LIBBUILTIN(_Block_object_dispose, "vvC*i<br>
 // Annotation function<br>
 BUILTIN(__builtin_annotation, "v.", "tn")<br>
<br>
+// Invariants<br>
+BUILTIN(__builtin_assume, "vb", "n")<br>
+<br>
 // Multiprecision Arithmetic Builtins.<br>
 BUILTIN(__builtin_addcb, "UcUcCUcCUcCUc*", "n")<br>
 BUILTIN(__builtin_addcs, "UsUsCUsCUsCUs*", "n")<br>
<br>
Modified: cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td?rev=217349&r1=217348&r2=217349&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td?rev=217349&r1=217348&r2=217349&view=diff</a><br>
==============================================================================<br>
--- cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td (original)<br>
+++ cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td Sun Sep  7 17:58:14 2014<br>
@@ -451,7 +451,7 @@ def note_strncat_wrong_size : Note<<br>
   "the terminating null byte">;<br>
<br>
 def warn_assume_side_effects : Warning<<br>
-  "the argument to __assume has side effects that will be discarded">,<br>
+  "the argument to %0 has side effects that will be discarded">,<br>
   InGroup<DiagGroup<"assume">>;<br>
<br>
 /// main()<br>
@@ -2078,8 +2078,9 @@ def err_no_accessor_for_property : Error<br>
 def error_cannot_find_suitable_accessor : Error<<br>
   "cannot find suitable %select{getter|setter}0 for property %1">;<br>
<br>
-def err_attribute_aligned_not_power_of_two : Error<<br>
+def err_alignment_not_power_of_two : Error<<br>
   "requested alignment is not a power of 2">;<br>
+<br>
 def err_attribute_aligned_too_great : Error<<br>
   "requested alignment must be %0 bytes or smaller">;<br>
 def warn_redeclaration_without_attribute_prev_attribute_ignored : Warning<<br>
<br>
Modified: cfe/trunk/include/clang/Sema/Sema.h<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Sema/Sema.h?rev=217349&r1=217348&r2=217349&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Sema/Sema.h?rev=217349&r1=217348&r2=217349&view=diff</a><br>
==============================================================================<br>
--- cfe/trunk/include/clang/Sema/Sema.h (original)<br>
+++ cfe/trunk/include/clang/Sema/Sema.h Sun Sep  7 17:58:14 2014<br>
@@ -8375,6 +8375,7 @@ public:<br>
 private:<br>
   bool SemaBuiltinPrefetch(CallExpr *TheCall);<br>
   bool SemaBuiltinAssume(CallExpr *TheCall);<br>
+  bool SemaBuiltinAssumeAligned(CallExpr *TheCall);<br>
   bool SemaBuiltinLongjmp(CallExpr *TheCall);<br>
   ExprResult SemaBuiltinAtomicOverloaded(ExprResult TheCallResult);<br>
   ExprResult SemaAtomicOpsOverloaded(ExprResult TheCallResult,<br>
<br>
Modified: cfe/trunk/lib/AST/ExprConstant.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/ExprConstant.cpp?rev=217349&r1=217348&r2=217349&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/ExprConstant.cpp?rev=217349&r1=217348&r2=217349&view=diff</a><br>
==============================================================================<br>
--- cfe/trunk/lib/AST/ExprConstant.cpp (original)<br>
+++ cfe/trunk/lib/AST/ExprConstant.cpp Sun Sep  7 17:58:14 2014<br>
@@ -6092,6 +6092,7 @@ bool IntExprEvaluator::VisitCallExpr(con<br>
     return Success(Operand, E);<br>
   }<br>
<br>
+  case Builtin::BI__builtin_assume_aligned:<br>
   case Builtin::BI__builtin_expect:<br>
     return Visit(E->getArg(0));<br></blockquote><div><br></div><div>We should evaluate (and discard) argument 1 and (if present) argument 2 here too, in case they have side-effects or are non-constant.</div><div> </div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
@@ -7967,6 +7968,7 @@ public:<br>
     default:<br>
       return ExprEvaluatorBaseTy::VisitCallExpr(E);<br>
     case Builtin::BI__assume:<br>
+    case Builtin::BI__builtin_assume:<br>
       // The argument is not evaluated!<br>
       return true;<br>
     }<br>
<br>
Modified: cfe/trunk/lib/CodeGen/CGBuiltin.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGBuiltin.cpp?rev=217349&r1=217348&r2=217349&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGBuiltin.cpp?rev=217349&r1=217348&r2=217349&view=diff</a><br>
==============================================================================<br>
--- cfe/trunk/lib/CodeGen/CGBuiltin.cpp (original)<br>
+++ cfe/trunk/lib/CodeGen/CGBuiltin.cpp Sun Sep  7 17:58:14 2014<br>
@@ -374,6 +374,27 @@ RValue CodeGenFunction::EmitBuiltinExpr(<br>
                                         "expval");<br>
     return RValue::get(Result);<br>
   }<br>
+  case Builtin::BI__builtin_assume_aligned: {<br>
+    Value *PtrValue = EmitScalarExpr(E->getArg(0));<br>
+    Value *OffsetValue =<br>
+      (E->getNumArgs() > 2) ? EmitScalarExpr(E->getArg(2)) : nullptr;<br>
+<br>
+    Value *AlignmentValue = EmitScalarExpr(E->getArg(1));<br>
+    ConstantInt *AlignmentCI = cast<ConstantInt>(AlignmentValue);<br>
+    unsigned Alignment = (unsigned) AlignmentCI->getZExtValue();<br>
+<br>
+    EmitAlignmentAssumption(PtrValue, Alignment, OffsetValue);<br>
+    return RValue::get(PtrValue);<br>
+  }<br>
+  case Builtin::BI__assume:<br>
+  case Builtin::BI__builtin_assume: {<br>
+    if (E->getArg(0)->HasSideEffects(getContext()))<br>
+      return RValue::get(nullptr);<br>
+<br>
+    Value *ArgValue = EmitScalarExpr(E->getArg(0));<br>
+    Value *FnAssume = CGM.getIntrinsic(Intrinsic::assume);<br>
+    return RValue::get(Builder.CreateCall(FnAssume, ArgValue));<br>
+  }<br>
   case Builtin::BI__builtin_bswap16:<br>
   case Builtin::BI__builtin_bswap32:<br>
   case Builtin::BI__builtin_bswap64: {<br>
@@ -1510,9 +1531,6 @@ RValue CodeGenFunction::EmitBuiltinExpr(<br>
   case Builtin::BI__noop:<br>
     // __noop always evaluates to an integer literal zero.<br>
     return RValue::get(ConstantInt::get(IntTy, 0));<br>
-  case Builtin::BI__assume:<br>
-    // Until LLVM supports assumptions at the IR level, this becomes nothing.<br>
-    return RValue::get(nullptr);<br>
   case Builtin::BI_InterlockedExchange:<br>
   case Builtin::BI_InterlockedExchangePointer:<br>
     return EmitBinaryAtomic(*this, llvm::AtomicRMWInst::Xchg, E);<br>
<br>
Modified: cfe/trunk/lib/CodeGen/CGExpr.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGExpr.cpp?rev=217349&r1=217348&r2=217349&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGExpr.cpp?rev=217349&r1=217348&r2=217349&view=diff</a><br>
==============================================================================<br>
--- cfe/trunk/lib/CodeGen/CGExpr.cpp (original)<br>
+++ cfe/trunk/lib/CodeGen/CGExpr.cpp Sun Sep  7 17:58:14 2014<br>
@@ -711,6 +711,34 @@ EmitComplexPrePostIncDec(const UnaryOper<br>
   return isPre ? IncVal : InVal;<br>
 }<br>
<br>
+void CodeGenFunction::EmitAlignmentAssumption(llvm::Value *PtrValue,<br>
+                                              unsigned Alignment,<br>
+                                              llvm::Value *OffsetValue) {<br>
+  llvm::Value *PtrIntValue =<br>
+    Builder.CreatePtrToInt(PtrValue, IntPtrTy, "ptrint");<br>
+<br>
+  llvm::Value *Mask = llvm::ConstantInt::get(IntPtrTy,<br>
+    Alignment > 0 ? Alignment - 1 : 0);<br>
+  if (OffsetValue) {<br>
+    bool IsOffsetZero = false;<br>
+    if (llvm::ConstantInt *CI = dyn_cast<llvm::ConstantInt>(OffsetValue))<br>
+      IsOffsetZero = CI->isZero();<br>
+<br>
+    if (!IsOffsetZero) {<br>
+      if (OffsetValue->getType() != IntPtrTy)<br>
+        OffsetValue = Builder.CreateIntCast(OffsetValue, IntPtrTy,<br>
+                        /*isSigned*/true, "offsetcast");<br>
+      PtrIntValue = Builder.CreateSub(PtrIntValue, OffsetValue, "offsetptr");<br>
+    }<br>
+  }<br>
+<br>
+  llvm::Value *Zero = llvm::ConstantInt::get(IntPtrTy, 0);<br>
+  llvm::Value *MaskedPtr = Builder.CreateAnd(PtrIntValue, Mask, "maskedptr");<br>
+  llvm::Value *InvCond = Builder.CreateICmpEQ(MaskedPtr, Zero, "maskcond");<br>
+<br>
+  llvm::Value *FnAssume = CGM.getIntrinsic(llvm::Intrinsic::assume);<br>
+  Builder.CreateCall(FnAssume, InvCond);<br>
+}<br>
<br>
 //===----------------------------------------------------------------------===//<br>
 //                         LValue Expression Emission<br>
<br>
Modified: cfe/trunk/lib/CodeGen/CodeGenFunction.h<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CodeGenFunction.h?rev=217349&r1=217348&r2=217349&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CodeGenFunction.h?rev=217349&r1=217348&r2=217349&view=diff</a><br>
==============================================================================<br>
--- cfe/trunk/lib/CodeGen/CodeGenFunction.h (original)<br>
+++ cfe/trunk/lib/CodeGen/CodeGenFunction.h Sun Sep  7 17:58:14 2014<br>
@@ -1743,6 +1743,10 @@ public:<br>
                                        bool isInc, bool isPre);<br>
   ComplexPairTy EmitComplexPrePostIncDec(const UnaryOperator *E, LValue LV,<br>
                                          bool isInc, bool isPre);<br>
+<br>
+  void EmitAlignmentAssumption(llvm::Value *PtrValue, unsigned Alignment,<br>
+                               llvm::Value *OffsetValue = nullptr);<br>
+<br>
   //===--------------------------------------------------------------------===//<br>
   //                            Declaration Emission<br>
   //===--------------------------------------------------------------------===//<br>
<br>
Modified: cfe/trunk/lib/Sema/SemaChecking.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaChecking.cpp?rev=217349&r1=217348&r2=217349&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaChecking.cpp?rev=217349&r1=217348&r2=217349&view=diff</a><br>
==============================================================================<br>
--- cfe/trunk/lib/Sema/SemaChecking.cpp (original)<br>
+++ cfe/trunk/lib/Sema/SemaChecking.cpp Sun Sep  7 17:58:14 2014<br>
@@ -189,9 +189,14 @@ Sema::CheckBuiltinFunctionCall(unsigned<br>
       return ExprError();<br>
     break;<br>
   case Builtin::BI__assume:<br>
+  case Builtin::BI__builtin_assume:<br>
     if (SemaBuiltinAssume(TheCall))<br>
       return ExprError();<br>
     break;<br>
+  case Builtin::BI__builtin_assume_aligned:<br>
+    if (SemaBuiltinAssumeAligned(TheCall))<br>
+      return ExprError();<br>
+    break;<br>
   case Builtin::BI__builtin_object_size:<br>
     if (SemaBuiltinConstantArgRange(TheCall, 1, 0, 3))<br>
       return ExprError();<br>
@@ -2059,7 +2064,46 @@ bool Sema::SemaBuiltinAssume(CallExpr *T<br>
<br>
   if (Arg->HasSideEffects(Context))<br>
     return Diag(Arg->getLocStart(), diag::warn_assume_side_effects)<br>
-      << Arg->getSourceRange();<br>
+      << Arg->getSourceRange()<br>
+      << cast<FunctionDecl>(TheCall->getCalleeDecl())->getIdentifier();<br>
+<br>
+  return false;<br>
+}<br>
+<br>
+/// Handle __builtin_assume_aligned. This is declared<br>
+/// as (const void*, size_t, ...) and can take one optional constant int arg.<br>
+bool Sema::SemaBuiltinAssumeAligned(CallExpr *TheCall) {<br>
+  unsigned NumArgs = TheCall->getNumArgs();<br>
+<br>
+  if (NumArgs > 3)<br>
+    return Diag(TheCall->getLocEnd(),<br>
+             diag::err_typecheck_call_too_many_args_at_most)<br>
+             << 0 /*function call*/ << 3 << NumArgs<br>
+             << TheCall->getSourceRange();<br>
+<br>
+  // The alignment must be a constant integer.<br>
+  Expr *Arg = TheCall->getArg(1);<br>
+<br>
+  // We can't check the value of a dependent argument.<br>
+  if (!Arg->isTypeDependent() && !Arg->isValueDependent()) {<br>
+    llvm::APSInt Result;<br>
+    if (SemaBuiltinConstantArg(TheCall, 1, Result))<br>
+      return true;<br>
+<br>
+    if (!Result.isPowerOf2())<br>
+      return Diag(TheCall->getLocStart(),<br>
+                  diag::err_alignment_not_power_of_two)<br>
+           << Arg->getSourceRange();<br>
+  }<br>
+<br>
+  if (NumArgs > 2) {<br>
+    ExprResult Arg(TheCall->getArg(2));<br>
+    InitializedEntity Entity = InitializedEntity::InitializeParameter(Context,<br>
+      Context.getSizeType(), false);<br>
+    Arg = PerformCopyInitialization(Entity, SourceLocation(), Arg);<br>
+    if (Arg.isInvalid()) return true;<br>
+    TheCall->setArg(2, Arg.get());<br>
+  }<br>
<br>
   return false;<br>
 }<br>
<br>
Modified: cfe/trunk/lib/Sema/SemaDeclAttr.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaDeclAttr.cpp?rev=217349&r1=217348&r2=217349&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaDeclAttr.cpp?rev=217349&r1=217348&r2=217349&view=diff</a><br>
==============================================================================<br>
--- cfe/trunk/lib/Sema/SemaDeclAttr.cpp (original)<br>
+++ cfe/trunk/lib/Sema/SemaDeclAttr.cpp Sun Sep  7 17:58:14 2014<br>
@@ -2786,7 +2786,7 @@ void Sema::AddAlignedAttr(SourceRange At<br>
   //   An alignment specification of zero has no effect.<br>
   if (!(TmpAttr.isAlignas() && !Alignment) &&<br>
       !llvm::isPowerOf2_64(Alignment.getZExtValue())) {<br>
-    Diag(AttrLoc, diag::err_attribute_aligned_not_power_of_two)<br>
+    Diag(AttrLoc, diag::err_alignment_not_power_of_two)<br>
       << E->getSourceRange();<br>
     return;<br>
   }<br>
<br>
Added: cfe/trunk/test/CodeGen/builtin-assume-aligned.c<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGen/builtin-assume-aligned.c?rev=217349&view=auto" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGen/builtin-assume-aligned.c?rev=217349&view=auto</a><br>
==============================================================================<br>
--- cfe/trunk/test/CodeGen/builtin-assume-aligned.c (added)<br>
+++ cfe/trunk/test/CodeGen/builtin-assume-aligned.c Sun Sep  7 17:58:14 2014<br>
@@ -0,0 +1,44 @@<br>
+// RUN: %clang_cc1 -triple x86_64-unknown-unknown -emit-llvm -o - %s | FileCheck %s<br>
+<br>
+// CHECK-LABEL: @test1<br>
+int test1(int *a) {<br>
+// CHECK: %ptrint = ptrtoint<br>
+// CHECK: %maskedptr = and i64 %ptrint, 31<br>
+// CHECK: %maskcond = icmp eq i64 %maskedptr, 0<br>
+// CHECK: call void @llvm.assume(i1 %maskcond)<br>
+  a = __builtin_assume_aligned(a, 32, 0ull);<br>
+  return a[0];<br>
+}<br>
+<br>
+// CHECK-LABEL: @test2<br>
+int test2(int *a) {<br>
+// CHECK: %ptrint = ptrtoint<br>
+// CHECK: %maskedptr = and i64 %ptrint, 31<br>
+// CHECK: %maskcond = icmp eq i64 %maskedptr, 0<br>
+// CHECK: call void @llvm.assume(i1 %maskcond)<br>
+  a = __builtin_assume_aligned(a, 32, 0);<br>
+  return a[0];<br>
+}<br>
+<br>
+// CHECK-LABEL: @test3<br>
+int test3(int *a) {<br>
+// CHECK: %ptrint = ptrtoint<br>
+// CHECK: %maskedptr = and i64 %ptrint, 31<br>
+// CHECK: %maskcond = icmp eq i64 %maskedptr, 0<br>
+// CHECK: call void @llvm.assume(i1 %maskcond)<br>
+  a = __builtin_assume_aligned(a, 32);<br>
+  return a[0];<br>
+}<br>
+<br>
+// CHECK-LABEL: @test4<br>
+int test4(int *a, int b) {<br>
+// CHECK-DAG: %ptrint = ptrtoint<br>
+// CHECK-DAG: %conv = sext i32<br>
+// CHECK: %offsetptr = sub i64 %ptrint, %conv<br>
+// CHECK: %maskedptr = and i64 %offsetptr, 31<br>
+// CHECK: %maskcond = icmp eq i64 %maskedptr, 0<br>
+// CHECK: call void @llvm.assume(i1 %maskcond)<br>
+  a = __builtin_assume_aligned(a, 32, b);<br>
+  return a[0];<br>
+}<br>
+<br>
<br>
Modified: cfe/trunk/test/CodeGen/builtin-assume.c<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGen/builtin-assume.c?rev=217349&r1=217348&r2=217349&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGen/builtin-assume.c?rev=217349&r1=217348&r2=217349&view=diff</a><br>
==============================================================================<br>
--- cfe/trunk/test/CodeGen/builtin-assume.c (original)<br>
+++ cfe/trunk/test/CodeGen/builtin-assume.c Sun Sep  7 17:58:14 2014<br>
@@ -1,8 +1,26 @@<br>
+// RUN: %clang_cc1 -triple x86_64-unknown-unknown -emit-llvm -o - %s | FileCheck %s<br>
 // RUN: %clang_cc1 -triple i386-mingw32 -fms-extensions -emit-llvm -o - %s | FileCheck %s<br>
<br>
 // CHECK-LABEL: @test1<br>
-int test1(int *a) {<br>
-  __assume(a != 0);<br>
+int test1(int *a, int i) {<br>
+// CHECK: %0 = load i32** %a.addr<br>
+// CHECK: %cmp = icmp ne i32* %0, null<br>
+// CHECK: call void @llvm.assume(i1 %cmp)<br>
+#ifdef _MSC_VER<br>
+  __assume(a != 0)<br>
+#else<br>
+  __builtin_assume(a != 0);<br>
+#endif<br>
+<br>
+// Nothing is generated for an assume with side effects...<br>
+// CHECK-NOT: load i32** %i.addr<br>
+// CHECK-NOT: call void @llvm.assume<br>
+#ifdef _MSC_VER<br>
+  __assume(++i != 0)<br>
+#else<br>
+  __builtin_assume(++i != 0);<br>
+#endif<br>
+<br>
   return a[0];<br>
 }<br>
<br>
<br>
Added: cfe/trunk/test/Sema/builtin-assume-aligned.c<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Sema/builtin-assume-aligned.c?rev=217349&view=auto" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Sema/builtin-assume-aligned.c?rev=217349&view=auto</a><br>
==============================================================================<br>
--- cfe/trunk/test/Sema/builtin-assume-aligned.c (added)<br>
+++ cfe/trunk/test/Sema/builtin-assume-aligned.c Sun Sep  7 17:58:14 2014<br>
@@ -0,0 +1,43 @@<br>
+// RUN: %clang_cc1 -fsyntax-only -verify %s<br>
+<br>
+int test1(int *a) {<br>
+  a = __builtin_assume_aligned(a, 32, 0ull);<br>
+  return a[0];<br>
+}<br>
+<br>
+int test2(int *a) {<br>
+  a = __builtin_assume_aligned(a, 32, 0);<br>
+  return a[0];<br>
+}<br>
+<br>
+int test3(int *a) {<br>
+  a = __builtin_assume_aligned(a, 32);<br>
+  return a[0];<br>
+}<br>
+<br>
+int test4(int *a) {<br>
+  a = __builtin_assume_aligned(a, -32); // expected-error {{requested alignment is not a power of 2}}<br>
+  a = __builtin_assume_aligned(a, 1ULL << 63);<br>
+  return a[0];<br>
+}<br>
+<br>
+int test5(int *a, unsigned *b) {<br>
+  a = __builtin_assume_aligned(a, 32, b); // expected-warning {{incompatible pointer to integer conversion passing 'unsigned int *' to parameter of type}}<br>
+  return a[0];<br>
+}<br>
+<br>
+int test6(int *a) {<br>
+  a = __builtin_assume_aligned(a, 32, 0, 0); // expected-error {{too many arguments to function call, expected at most 3, have 4}}<br>
+  return a[0];<br>
+}<br>
+<br>
+int test7(int *a) {<br>
+  a = __builtin_assume_aligned(a, 31); // expected-error {{requested alignment is not a power of 2}}<br>
+  return a[0];<br>
+}<br>
+<br>
+int test8(int *a, int j) {<br>
+  a = __builtin_assume_aligned(a, j); // expected-error {{must be a constant integer}}<br>
+  return a[0];<br>
+}<br>
+<br>
<br>
Modified: cfe/trunk/test/Sema/builtin-assume.c<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Sema/builtin-assume.c?rev=217349&r1=217348&r2=217349&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Sema/builtin-assume.c?rev=217349&r1=217348&r2=217349&view=diff</a><br>
==============================================================================<br>
--- cfe/trunk/test/Sema/builtin-assume.c (original)<br>
+++ cfe/trunk/test/Sema/builtin-assume.c Sun Sep  7 17:58:14 2014<br>
@@ -1,11 +1,18 @@<br>
 // RUN: %clang_cc1 -triple i386-mingw32 -fms-extensions -fsyntax-only -verify %s<br>
+// RUN: %clang_cc1 -triple x86_64-unknown-unknown -fsyntax-only -verify %s<br>
<br>
 int foo(int *a, int i) {<br>
+#ifdef _MSC_VER<br>
   __assume(i != 4);<br>
-  __assume(++i > 2); //expected-warning {{the argument to __assume has side effects that will be discarded}}<br>
+  __assume(++i > 2); //expected-warning {{the argument to '__assume' has side effects that will be discarded}}<br>
<br>
   int test = sizeof(struct{char qq[(__assume(i != 5), 7)];});<br>
+#else<br>
+  __builtin_assume(i != 4);<br>
+  __builtin_assume(++i > 2); //expected-warning {{the argument to '__builtin_assume' has side effects that will be discarded}}<br>
<br>
+  int test = sizeof(struct{char qq[(__builtin_assume(i != 5), 7)];});<br>
+#endif<br>
   return a[i];<br>
 }<br>
<br>
<br>
Added: cfe/trunk/test/SemaCXX/builtin-assume-aligned-tmpl.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaCXX/builtin-assume-aligned-tmpl.cpp?rev=217349&view=auto" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaCXX/builtin-assume-aligned-tmpl.cpp?rev=217349&view=auto</a><br>
==============================================================================<br>
--- cfe/trunk/test/SemaCXX/builtin-assume-aligned-tmpl.cpp (added)<br>
+++ cfe/trunk/test/SemaCXX/builtin-assume-aligned-tmpl.cpp Sun Sep  7 17:58:14 2014<br>
@@ -0,0 +1,22 @@<br>
+// RUN: %clang_cc1 -fsyntax-only -verify %s<br>
+<br>
+template<int z><br>
+int test9(int *a) {<br>
+  a = (int *) __builtin_assume_aligned(a, z + 1); // expected-error {{requested alignment is not a power of 2}}<br>
+  return a[0];<br>
+}<br>
+<br>
+void test9i(int *a) {<br>
+  test9<42>(a); // expected-note {{in instantiation of function template specialization 'test9<42>' requested here}}<br>
+}<br>
+<br>
+template<typename T><br>
+int test10(int *a, T z) {<br>
+  a = (int *) __builtin_assume_aligned(a, z + 1); // expected-error {{must be a constant integer}}<br>
+  return a[0];<br>
+}<br>
+<br>
+int test10i(int *a) {<br>
+  return test10(a, 42); // expected-note {{in instantiation of function template specialization 'test10<int>' requested here}}<br>
+}<br>
+<br>
<br>
<br>
_______________________________________________<br>
cfe-commits mailing list<br>
<a href="mailto:cfe-commits@cs.uiuc.edu">cfe-commits@cs.uiuc.edu</a><br>
<a href="http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits" target="_blank">http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits</a><br>
</blockquote></div><br></div></div>