r217349 - Add __builtin_assume and __builtin_assume_aligned using @llvm.assume.

Hal Finkel hfinkel at anl.gov
Sun Sep 7 15:58:15 PDT 2014


Author: hfinkel
Date: Sun Sep  7 17:58:14 2014
New Revision: 217349

URL: http://llvm.org/viewvc/llvm-project?rev=217349&view=rev
Log:
Add __builtin_assume and __builtin_assume_aligned using @llvm.assume.

This makes use of the recently-added @llvm.assume intrinsic to implement a
__builtin_assume(bool) intrinsic (to provide additional information to the
optimizer). This hooks up __assume in MS-compatibility mode to mirror
__builtin_assume (the semantics have been intentionally kept compatible), and
implements GCC's __builtin_assume_aligned as assume((p - o) & mask == 0). LLVM
now contains special logic to deal with assumptions of this form.

Added:
    cfe/trunk/test/CodeGen/builtin-assume-aligned.c
    cfe/trunk/test/Sema/builtin-assume-aligned.c
    cfe/trunk/test/SemaCXX/builtin-assume-aligned-tmpl.cpp
Modified:
    cfe/trunk/docs/LanguageExtensions.rst
    cfe/trunk/include/clang/Basic/Builtins.def
    cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td
    cfe/trunk/include/clang/Sema/Sema.h
    cfe/trunk/lib/AST/ExprConstant.cpp
    cfe/trunk/lib/CodeGen/CGBuiltin.cpp
    cfe/trunk/lib/CodeGen/CGExpr.cpp
    cfe/trunk/lib/CodeGen/CodeGenFunction.h
    cfe/trunk/lib/Sema/SemaChecking.cpp
    cfe/trunk/lib/Sema/SemaDeclAttr.cpp
    cfe/trunk/test/CodeGen/builtin-assume.c
    cfe/trunk/test/Sema/builtin-assume.c

Modified: cfe/trunk/docs/LanguageExtensions.rst
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/docs/LanguageExtensions.rst?rev=217349&r1=217348&r2=217349&view=diff
==============================================================================
--- cfe/trunk/docs/LanguageExtensions.rst (original)
+++ cfe/trunk/docs/LanguageExtensions.rst Sun Sep  7 17:58:14 2014
@@ -1228,8 +1228,9 @@ Builtin Functions
 Clang supports a number of builtin library functions with the same syntax as
 GCC, including things like ``__builtin_nan``, ``__builtin_constant_p``,
 ``__builtin_choose_expr``, ``__builtin_types_compatible_p``,
-``__sync_fetch_and_add``, etc.  In addition to the GCC builtins, Clang supports
-a number of builtins that GCC does not, which are listed here.
+``__builtin_assume_aligned``, ``__sync_fetch_and_add``, etc.  In addition to
+the GCC builtins, Clang supports a number of builtins that GCC does not, which
+are listed here.
 
 Please note that Clang does not and will not support all of the GCC builtins
 for vector operations.  Instead of using builtins, you should use the functions
@@ -1239,6 +1240,42 @@ implemented directly in terms of :ref:`e
 <langext-vectors>` instead of builtins, in order to reduce the number of
 builtins that we need to implement.
 
+``__builtin_assume``
+------------------------------
+
+``__builtin_assume`` is used to provide the optimizer with a boolean
+invariant that is defined to be true.
+
+**Syntax**:
+
+.. code-block:: c++
+
+  __builtin_assume(bool)
+
+**Example of Use**:
+
+.. code-block:: c++
+
+  int foo(int x) {
+    __builtin_assume(x != 0);
+
+    // The optimizer may short-circuit this check using the invariant.
+    if (x == 0)
+      return do_something();
+
+    return do_something_else();
+  }
+
+**Description**:
+
+The boolean argument to this function is defined to be true. The optimizer may
+analyze the form of the expression provided as the argument and deduce from
+that information used to optimize the program. If the condition is violated
+during execution, the behavior is undefined. The argument itself is never
+evaluated, so any side effects of the expression will be discarded.
+
+Query for this feature with ``__has_builtin(__builtin_assume)``.
+
 ``__builtin_readcyclecounter``
 ------------------------------
 

Modified: cfe/trunk/include/clang/Basic/Builtins.def
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/Builtins.def?rev=217349&r1=217348&r2=217349&view=diff
==============================================================================
--- cfe/trunk/include/clang/Basic/Builtins.def (original)
+++ cfe/trunk/include/clang/Basic/Builtins.def Sun Sep  7 17:58:14 2014
@@ -412,6 +412,7 @@ BUILTIN(__builtin_va_start, "vA.", "nt")
 BUILTIN(__builtin_va_end, "vA", "n")
 BUILTIN(__builtin_va_copy, "vAA", "n")
 BUILTIN(__builtin_stdarg_start, "vA.", "n")
+BUILTIN(__builtin_assume_aligned, "v*vC*z.", "nc")
 BUILTIN(__builtin_bcmp, "iv*v*z", "n")
 BUILTIN(__builtin_bcopy, "vv*v*z", "n")
 BUILTIN(__builtin_bzero, "vv*z", "nF")
@@ -1173,6 +1174,9 @@ LIBBUILTIN(_Block_object_dispose, "vvC*i
 // Annotation function
 BUILTIN(__builtin_annotation, "v.", "tn")
 
+// Invariants
+BUILTIN(__builtin_assume, "vb", "n")
+
 // Multiprecision Arithmetic Builtins.
 BUILTIN(__builtin_addcb, "UcUcCUcCUcCUc*", "n")
 BUILTIN(__builtin_addcs, "UsUsCUsCUsCUs*", "n")

Modified: cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td?rev=217349&r1=217348&r2=217349&view=diff
==============================================================================
--- cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td (original)
+++ cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td Sun Sep  7 17:58:14 2014
@@ -451,7 +451,7 @@ def note_strncat_wrong_size : Note<
   "the terminating null byte">;
 
 def warn_assume_side_effects : Warning<
-  "the argument to __assume has side effects that will be discarded">,
+  "the argument to %0 has side effects that will be discarded">,
   InGroup<DiagGroup<"assume">>;
 
 /// main()
@@ -2078,8 +2078,9 @@ def err_no_accessor_for_property : Error
 def error_cannot_find_suitable_accessor : Error<
   "cannot find suitable %select{getter|setter}0 for property %1">;
 
-def err_attribute_aligned_not_power_of_two : Error<
+def err_alignment_not_power_of_two : Error<
   "requested alignment is not a power of 2">;
+
 def err_attribute_aligned_too_great : Error<
   "requested alignment must be %0 bytes or smaller">;
 def warn_redeclaration_without_attribute_prev_attribute_ignored : Warning<

Modified: cfe/trunk/include/clang/Sema/Sema.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Sema/Sema.h?rev=217349&r1=217348&r2=217349&view=diff
==============================================================================
--- cfe/trunk/include/clang/Sema/Sema.h (original)
+++ cfe/trunk/include/clang/Sema/Sema.h Sun Sep  7 17:58:14 2014
@@ -8375,6 +8375,7 @@ public:
 private:
   bool SemaBuiltinPrefetch(CallExpr *TheCall);
   bool SemaBuiltinAssume(CallExpr *TheCall);
+  bool SemaBuiltinAssumeAligned(CallExpr *TheCall);
   bool SemaBuiltinLongjmp(CallExpr *TheCall);
   ExprResult SemaBuiltinAtomicOverloaded(ExprResult TheCallResult);
   ExprResult SemaAtomicOpsOverloaded(ExprResult TheCallResult,

Modified: cfe/trunk/lib/AST/ExprConstant.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/ExprConstant.cpp?rev=217349&r1=217348&r2=217349&view=diff
==============================================================================
--- cfe/trunk/lib/AST/ExprConstant.cpp (original)
+++ cfe/trunk/lib/AST/ExprConstant.cpp Sun Sep  7 17:58:14 2014
@@ -6092,6 +6092,7 @@ bool IntExprEvaluator::VisitCallExpr(con
     return Success(Operand, E);
   }
 
+  case Builtin::BI__builtin_assume_aligned:
   case Builtin::BI__builtin_expect:
     return Visit(E->getArg(0));
 
@@ -7967,6 +7968,7 @@ public:
     default:
       return ExprEvaluatorBaseTy::VisitCallExpr(E);
     case Builtin::BI__assume:
+    case Builtin::BI__builtin_assume:
       // The argument is not evaluated!
       return true;
     }

Modified: cfe/trunk/lib/CodeGen/CGBuiltin.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGBuiltin.cpp?rev=217349&r1=217348&r2=217349&view=diff
==============================================================================
--- cfe/trunk/lib/CodeGen/CGBuiltin.cpp (original)
+++ cfe/trunk/lib/CodeGen/CGBuiltin.cpp Sun Sep  7 17:58:14 2014
@@ -374,6 +374,27 @@ RValue CodeGenFunction::EmitBuiltinExpr(
                                         "expval");
     return RValue::get(Result);
   }
+  case Builtin::BI__builtin_assume_aligned: {
+    Value *PtrValue = EmitScalarExpr(E->getArg(0));
+    Value *OffsetValue =
+      (E->getNumArgs() > 2) ? EmitScalarExpr(E->getArg(2)) : nullptr;
+
+    Value *AlignmentValue = EmitScalarExpr(E->getArg(1));
+    ConstantInt *AlignmentCI = cast<ConstantInt>(AlignmentValue);
+    unsigned Alignment = (unsigned) AlignmentCI->getZExtValue();
+
+    EmitAlignmentAssumption(PtrValue, Alignment, OffsetValue);
+    return RValue::get(PtrValue);
+  }
+  case Builtin::BI__assume:
+  case Builtin::BI__builtin_assume: {
+    if (E->getArg(0)->HasSideEffects(getContext()))
+      return RValue::get(nullptr);
+
+    Value *ArgValue = EmitScalarExpr(E->getArg(0));
+    Value *FnAssume = CGM.getIntrinsic(Intrinsic::assume);
+    return RValue::get(Builder.CreateCall(FnAssume, ArgValue));
+  }
   case Builtin::BI__builtin_bswap16:
   case Builtin::BI__builtin_bswap32:
   case Builtin::BI__builtin_bswap64: {
@@ -1510,9 +1531,6 @@ RValue CodeGenFunction::EmitBuiltinExpr(
   case Builtin::BI__noop:
     // __noop always evaluates to an integer literal zero.
     return RValue::get(ConstantInt::get(IntTy, 0));
-  case Builtin::BI__assume:
-    // Until LLVM supports assumptions at the IR level, this becomes nothing.
-    return RValue::get(nullptr);
   case Builtin::BI_InterlockedExchange:
   case Builtin::BI_InterlockedExchangePointer:
     return EmitBinaryAtomic(*this, llvm::AtomicRMWInst::Xchg, E);

Modified: cfe/trunk/lib/CodeGen/CGExpr.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGExpr.cpp?rev=217349&r1=217348&r2=217349&view=diff
==============================================================================
--- cfe/trunk/lib/CodeGen/CGExpr.cpp (original)
+++ cfe/trunk/lib/CodeGen/CGExpr.cpp Sun Sep  7 17:58:14 2014
@@ -711,6 +711,34 @@ EmitComplexPrePostIncDec(const UnaryOper
   return isPre ? IncVal : InVal;
 }
 
+void CodeGenFunction::EmitAlignmentAssumption(llvm::Value *PtrValue,
+                                              unsigned Alignment,
+                                              llvm::Value *OffsetValue) {
+  llvm::Value *PtrIntValue =
+    Builder.CreatePtrToInt(PtrValue, IntPtrTy, "ptrint");
+
+  llvm::Value *Mask = llvm::ConstantInt::get(IntPtrTy,
+    Alignment > 0 ? Alignment - 1 : 0);
+  if (OffsetValue) {
+    bool IsOffsetZero = false;
+    if (llvm::ConstantInt *CI = dyn_cast<llvm::ConstantInt>(OffsetValue))
+      IsOffsetZero = CI->isZero();
+
+    if (!IsOffsetZero) {
+      if (OffsetValue->getType() != IntPtrTy)
+        OffsetValue = Builder.CreateIntCast(OffsetValue, IntPtrTy,
+                        /*isSigned*/true, "offsetcast");
+      PtrIntValue = Builder.CreateSub(PtrIntValue, OffsetValue, "offsetptr");
+    }
+  }
+
+  llvm::Value *Zero = llvm::ConstantInt::get(IntPtrTy, 0);
+  llvm::Value *MaskedPtr = Builder.CreateAnd(PtrIntValue, Mask, "maskedptr");
+  llvm::Value *InvCond = Builder.CreateICmpEQ(MaskedPtr, Zero, "maskcond");
+
+  llvm::Value *FnAssume = CGM.getIntrinsic(llvm::Intrinsic::assume);
+  Builder.CreateCall(FnAssume, InvCond);
+}
 
 //===----------------------------------------------------------------------===//
 //                         LValue Expression Emission

Modified: cfe/trunk/lib/CodeGen/CodeGenFunction.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CodeGenFunction.h?rev=217349&r1=217348&r2=217349&view=diff
==============================================================================
--- cfe/trunk/lib/CodeGen/CodeGenFunction.h (original)
+++ cfe/trunk/lib/CodeGen/CodeGenFunction.h Sun Sep  7 17:58:14 2014
@@ -1743,6 +1743,10 @@ public:
                                        bool isInc, bool isPre);
   ComplexPairTy EmitComplexPrePostIncDec(const UnaryOperator *E, LValue LV,
                                          bool isInc, bool isPre);
+
+  void EmitAlignmentAssumption(llvm::Value *PtrValue, unsigned Alignment,
+                               llvm::Value *OffsetValue = nullptr);
+
   //===--------------------------------------------------------------------===//
   //                            Declaration Emission
   //===--------------------------------------------------------------------===//

Modified: cfe/trunk/lib/Sema/SemaChecking.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaChecking.cpp?rev=217349&r1=217348&r2=217349&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaChecking.cpp (original)
+++ cfe/trunk/lib/Sema/SemaChecking.cpp Sun Sep  7 17:58:14 2014
@@ -189,9 +189,14 @@ Sema::CheckBuiltinFunctionCall(unsigned
       return ExprError();
     break;
   case Builtin::BI__assume:
+  case Builtin::BI__builtin_assume:
     if (SemaBuiltinAssume(TheCall))
       return ExprError();
     break;
+  case Builtin::BI__builtin_assume_aligned:
+    if (SemaBuiltinAssumeAligned(TheCall))
+      return ExprError();
+    break;
   case Builtin::BI__builtin_object_size:
     if (SemaBuiltinConstantArgRange(TheCall, 1, 0, 3))
       return ExprError();
@@ -2059,7 +2064,46 @@ bool Sema::SemaBuiltinAssume(CallExpr *T
 
   if (Arg->HasSideEffects(Context))
     return Diag(Arg->getLocStart(), diag::warn_assume_side_effects)
-      << Arg->getSourceRange();
+      << Arg->getSourceRange()
+      << cast<FunctionDecl>(TheCall->getCalleeDecl())->getIdentifier();
+
+  return false;
+}
+
+/// Handle __builtin_assume_aligned. This is declared
+/// as (const void*, size_t, ...) and can take one optional constant int arg.
+bool Sema::SemaBuiltinAssumeAligned(CallExpr *TheCall) {
+  unsigned NumArgs = TheCall->getNumArgs();
+
+  if (NumArgs > 3)
+    return Diag(TheCall->getLocEnd(),
+             diag::err_typecheck_call_too_many_args_at_most)
+             << 0 /*function call*/ << 3 << NumArgs
+             << TheCall->getSourceRange();
+
+  // The alignment must be a constant integer.
+  Expr *Arg = TheCall->getArg(1);
+
+  // We can't check the value of a dependent argument.
+  if (!Arg->isTypeDependent() && !Arg->isValueDependent()) {
+    llvm::APSInt Result;
+    if (SemaBuiltinConstantArg(TheCall, 1, Result))
+      return true;
+
+    if (!Result.isPowerOf2())
+      return Diag(TheCall->getLocStart(),
+                  diag::err_alignment_not_power_of_two)
+           << Arg->getSourceRange();
+  }
+
+  if (NumArgs > 2) {
+    ExprResult Arg(TheCall->getArg(2));
+    InitializedEntity Entity = InitializedEntity::InitializeParameter(Context,
+      Context.getSizeType(), false);
+    Arg = PerformCopyInitialization(Entity, SourceLocation(), Arg);
+    if (Arg.isInvalid()) return true;
+    TheCall->setArg(2, Arg.get());
+  }
 
   return false;
 }

Modified: cfe/trunk/lib/Sema/SemaDeclAttr.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaDeclAttr.cpp?rev=217349&r1=217348&r2=217349&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaDeclAttr.cpp (original)
+++ cfe/trunk/lib/Sema/SemaDeclAttr.cpp Sun Sep  7 17:58:14 2014
@@ -2786,7 +2786,7 @@ void Sema::AddAlignedAttr(SourceRange At
   //   An alignment specification of zero has no effect.
   if (!(TmpAttr.isAlignas() && !Alignment) &&
       !llvm::isPowerOf2_64(Alignment.getZExtValue())) {
-    Diag(AttrLoc, diag::err_attribute_aligned_not_power_of_two)
+    Diag(AttrLoc, diag::err_alignment_not_power_of_two)
       << E->getSourceRange();
     return;
   }

Added: cfe/trunk/test/CodeGen/builtin-assume-aligned.c
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGen/builtin-assume-aligned.c?rev=217349&view=auto
==============================================================================
--- cfe/trunk/test/CodeGen/builtin-assume-aligned.c (added)
+++ cfe/trunk/test/CodeGen/builtin-assume-aligned.c Sun Sep  7 17:58:14 2014
@@ -0,0 +1,44 @@
+// RUN: %clang_cc1 -triple x86_64-unknown-unknown -emit-llvm -o - %s | FileCheck %s
+
+// CHECK-LABEL: @test1
+int test1(int *a) {
+// CHECK: %ptrint = ptrtoint
+// CHECK: %maskedptr = and i64 %ptrint, 31
+// CHECK: %maskcond = icmp eq i64 %maskedptr, 0
+// CHECK: call void @llvm.assume(i1 %maskcond)
+  a = __builtin_assume_aligned(a, 32, 0ull);
+  return a[0];
+}
+
+// CHECK-LABEL: @test2
+int test2(int *a) {
+// CHECK: %ptrint = ptrtoint
+// CHECK: %maskedptr = and i64 %ptrint, 31
+// CHECK: %maskcond = icmp eq i64 %maskedptr, 0
+// CHECK: call void @llvm.assume(i1 %maskcond)
+  a = __builtin_assume_aligned(a, 32, 0);
+  return a[0];
+}
+
+// CHECK-LABEL: @test3
+int test3(int *a) {
+// CHECK: %ptrint = ptrtoint
+// CHECK: %maskedptr = and i64 %ptrint, 31
+// CHECK: %maskcond = icmp eq i64 %maskedptr, 0
+// CHECK: call void @llvm.assume(i1 %maskcond)
+  a = __builtin_assume_aligned(a, 32);
+  return a[0];
+}
+
+// CHECK-LABEL: @test4
+int test4(int *a, int b) {
+// CHECK-DAG: %ptrint = ptrtoint
+// CHECK-DAG: %conv = sext i32
+// CHECK: %offsetptr = sub i64 %ptrint, %conv
+// CHECK: %maskedptr = and i64 %offsetptr, 31
+// CHECK: %maskcond = icmp eq i64 %maskedptr, 0
+// CHECK: call void @llvm.assume(i1 %maskcond)
+  a = __builtin_assume_aligned(a, 32, b);
+  return a[0];
+}
+

Modified: cfe/trunk/test/CodeGen/builtin-assume.c
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGen/builtin-assume.c?rev=217349&r1=217348&r2=217349&view=diff
==============================================================================
--- cfe/trunk/test/CodeGen/builtin-assume.c (original)
+++ cfe/trunk/test/CodeGen/builtin-assume.c Sun Sep  7 17:58:14 2014
@@ -1,8 +1,26 @@
+// RUN: %clang_cc1 -triple x86_64-unknown-unknown -emit-llvm -o - %s | FileCheck %s
 // RUN: %clang_cc1 -triple i386-mingw32 -fms-extensions -emit-llvm -o - %s | FileCheck %s
 
 // CHECK-LABEL: @test1
-int test1(int *a) {
-  __assume(a != 0);
+int test1(int *a, int i) {
+// CHECK: %0 = load i32** %a.addr
+// CHECK: %cmp = icmp ne i32* %0, null
+// CHECK: call void @llvm.assume(i1 %cmp)
+#ifdef _MSC_VER
+  __assume(a != 0)
+#else
+  __builtin_assume(a != 0);
+#endif
+
+// Nothing is generated for an assume with side effects...
+// CHECK-NOT: load i32** %i.addr
+// CHECK-NOT: call void @llvm.assume
+#ifdef _MSC_VER
+  __assume(++i != 0)
+#else
+  __builtin_assume(++i != 0);
+#endif
+
   return a[0];
 }
 

Added: cfe/trunk/test/Sema/builtin-assume-aligned.c
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Sema/builtin-assume-aligned.c?rev=217349&view=auto
==============================================================================
--- cfe/trunk/test/Sema/builtin-assume-aligned.c (added)
+++ cfe/trunk/test/Sema/builtin-assume-aligned.c Sun Sep  7 17:58:14 2014
@@ -0,0 +1,43 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+
+int test1(int *a) {
+  a = __builtin_assume_aligned(a, 32, 0ull);
+  return a[0];
+}
+
+int test2(int *a) {
+  a = __builtin_assume_aligned(a, 32, 0);
+  return a[0];
+}
+
+int test3(int *a) {
+  a = __builtin_assume_aligned(a, 32);
+  return a[0];
+}
+
+int test4(int *a) {
+  a = __builtin_assume_aligned(a, -32); // expected-error {{requested alignment is not a power of 2}}
+  a = __builtin_assume_aligned(a, 1ULL << 63);
+  return a[0];
+}
+
+int test5(int *a, unsigned *b) {
+  a = __builtin_assume_aligned(a, 32, b); // expected-warning {{incompatible pointer to integer conversion passing 'unsigned int *' to parameter of type}}
+  return a[0];
+}
+
+int test6(int *a) {
+  a = __builtin_assume_aligned(a, 32, 0, 0); // expected-error {{too many arguments to function call, expected at most 3, have 4}}
+  return a[0];
+}
+
+int test7(int *a) {
+  a = __builtin_assume_aligned(a, 31); // expected-error {{requested alignment is not a power of 2}}
+  return a[0];
+}
+
+int test8(int *a, int j) {
+  a = __builtin_assume_aligned(a, j); // expected-error {{must be a constant integer}}
+  return a[0];
+}
+

Modified: cfe/trunk/test/Sema/builtin-assume.c
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Sema/builtin-assume.c?rev=217349&r1=217348&r2=217349&view=diff
==============================================================================
--- cfe/trunk/test/Sema/builtin-assume.c (original)
+++ cfe/trunk/test/Sema/builtin-assume.c Sun Sep  7 17:58:14 2014
@@ -1,11 +1,18 @@
 // RUN: %clang_cc1 -triple i386-mingw32 -fms-extensions -fsyntax-only -verify %s
+// RUN: %clang_cc1 -triple x86_64-unknown-unknown -fsyntax-only -verify %s
 
 int foo(int *a, int i) {
+#ifdef _MSC_VER
   __assume(i != 4);
-  __assume(++i > 2); //expected-warning {{the argument to __assume has side effects that will be discarded}}
+  __assume(++i > 2); //expected-warning {{the argument to '__assume' has side effects that will be discarded}}
 
   int test = sizeof(struct{char qq[(__assume(i != 5), 7)];});
+#else
+  __builtin_assume(i != 4);
+  __builtin_assume(++i > 2); //expected-warning {{the argument to '__builtin_assume' has side effects that will be discarded}}
 
+  int test = sizeof(struct{char qq[(__builtin_assume(i != 5), 7)];});
+#endif
   return a[i];
 }
 

Added: cfe/trunk/test/SemaCXX/builtin-assume-aligned-tmpl.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaCXX/builtin-assume-aligned-tmpl.cpp?rev=217349&view=auto
==============================================================================
--- cfe/trunk/test/SemaCXX/builtin-assume-aligned-tmpl.cpp (added)
+++ cfe/trunk/test/SemaCXX/builtin-assume-aligned-tmpl.cpp Sun Sep  7 17:58:14 2014
@@ -0,0 +1,22 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+
+template<int z>
+int test9(int *a) {
+  a = (int *) __builtin_assume_aligned(a, z + 1); // expected-error {{requested alignment is not a power of 2}}
+  return a[0];
+}
+
+void test9i(int *a) {
+  test9<42>(a); // expected-note {{in instantiation of function template specialization 'test9<42>' requested here}}
+}
+
+template<typename T>
+int test10(int *a, T z) {
+  a = (int *) __builtin_assume_aligned(a, z + 1); // expected-error {{must be a constant integer}}
+  return a[0];
+}
+
+int test10i(int *a) {
+  return test10(a, 42); // expected-note {{in instantiation of function template specialization 'test10<int>' requested here}}
+}
+





More information about the cfe-commits mailing list