[PATCH] D117829: [Clang] Add integer add/mul reduction builtins

2022-01-21 Thread Florian Hahn via Phabricator via cfe-commits
fhahn added a subscriber: junaire.
fhahn added a comment.

Thanks for the patch!

> For other reductions, we've tried to share builtins for float/integer 
> vectors, but the fadd/fmul reduction builtins also take a starting value 
> argument. Technically I could support float by using default values, but 
> we're probably better off with specific fadd/fmul reduction builtins for both 
> arguments.

Just to double check, you mean LLVM intrinsics here, right? As specified, the 
Clang `__builtin_reduce_add` should support both integer and floating point 
reductions. Do you think that's problematic? If so, we should update the spec.

For float reductions, the key questions is how to lower it. Unfortunately 
`llvm.vector.reduce.fadd` reductions at the moment are either unordered or 
sequential, but we need a particular order. @junaire has been looking into this 
and put up D117480  as an option to extend 
the intrinsic to have a dedicated order argument. That would make it easy for 
backends like AArch64 to select the right reduction instruction. Alternatively 
clang could also create the expanded reduction tree to start with. But we 
really want to lower this to native reduction instructions if we can.

In D117829#3259588 , @RKSimon wrote:

> I should mention - according to 
> https://clang.llvm.org/docs/LanguageExtensions.html `__builtin_reduce_add()` 
> already exists, which I don't think is true.

Do you mean it is listed in the docs but not implemented yet? That's true, the 
docs specified the whole set of proposed builtins from the start, regardless of 
implementation status.

FWIW, I think we intentionally did not specify `__builtin_reduce_mul` to start 
with, because it is very prone to overflows for integer vectors. Not saying 
that we cannot add it, but it would at least require updating the extension 
documentation. @scanon  might have additional feedback. In any case, it might 
be good to only handle the `add` case in this patch.




Comment at: clang/lib/Sema/SemaChecking.cpp:2263
   // These builtins support vectors of integers only.
+  case Builtin::BI__builtin_reduce_add:
+  case Builtin::BI__builtin_reduce_mul:

`_add` should also support floats, add a TODO?


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D117829/new/

https://reviews.llvm.org/D117829

___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D117798: [X86] Remove __builtin_ia32_pmax/min intrinsics and use generic __builtin_elementwise_max/min

2022-01-21 Thread Florian Hahn via Phabricator via cfe-commits
fhahn accepted this revision.
fhahn added a comment.

Thanks for the patch, it's great to see!


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D117798/new/

https://reviews.llvm.org/D117798

___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D117829: [Clang] Add integer add/mul reduction builtins

2022-01-21 Thread Florian Hahn via Phabricator via cfe-commits
fhahn added a comment.

In D117829#3260772 , @RKSimon wrote:

> I'm happy to continue with this just for integers or wait until we have a 
> plan for floats as well. I guess we need to decide if we want to support the 
> starting value in the fadd/fmul intrinsics from the builtin or not? If we 
> don't then adding float support to the add/mul reduction builtins now (or 
> later on) would just involve using default starting values, if we do then we 
> probably need a separate fadd/fmul builtin.

I'm not sure if there's a major benefit of specifying the start value? Unless 
there is, I think we should not add a start value argument.

> Or we could add starting values to the add/mul reduction builtins as well and 
> we manually insert a scalar post-reduction add/mul instruction in cgbuiltin?
>
> wrt float orders, currently the avx512f reductions attach fmf attributes when 
> the builtin is translated to the intrinsic: 
> https://github.com/llvm/llvm-project/blob/d2012d965d60c3258b3a69d024491698f8aec386/clang/lib/CodeGen/CGBuiltin.cpp#L14070

I am not familiar how exactly `ia32_reduce_fadd_pd512` & co are specified, but 
it looks like adding `reassoicate` to the intrinsic call there might be 
incorrect technically, i.e. calming the order does not matter, while I assume 
the C builtin guarantees a particular order? It might not result in an actual 
mis-compile on X86, because the X86 backend kind of guarantees that reductions 
with `reassoicate` are lowered exactly as the C builtin requires (relying on 
some kind of secret handshake between frontend & backend).

As discussed in  D117480  this seems like a 
major weakness in how `llvm.vector.reduce.fadd` is specified. As long as it is 
only used for target specific builtins, things might work out fine in most 
cases, but different targets might lower `reassoicate` reductions differently. 
Also, things might fall apart if the middle end uses the `reassoicate` property 
during a transform that changes the reduction order.

> We might be able to get away with just expecting users to handle this with 
> pragmas in code?

If the user allows reassoication via a pragma/flag, we can use the reduction 
builtin at the moment without problems. The motivation behind specifying a well 
defined order that can be lowered efficiently by targets is to guarantee 
portable results by default. This is important for uses cases where the 
builtins are used in code that's executed on different platforms.

> I was planning to see if that would work for the avx512f fmin/fmax reduction 
> intrinsics so I can use `__builtin_reduce_min/max`.

There shouldn't be any problem with fmin/fmax, as the result should be 
independent of the evaluation order IIUC.

> I'm mainly interested in `__builtin_reduce_mul` as avx512f requires it - the 
> (few) cases I've see it used have always involved char/short pixel data, 
> extended to int/long before the mul reduction to address the overflow issues.

Sounds reasonable!  As mentioned earlier, it would be good to do that as 
separate patch, also updating LanguageExtensions.rst.


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D117829/new/

https://reviews.llvm.org/D117829

___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D118259: [AArch64] Adjust aarch64-neon-intrinsics-constrained test and un-XFAIL

2022-01-27 Thread Florian Hahn via Phabricator via cfe-commits
fhahn added a comment.

Does this clang test actually need to check the generated assembly? Shouldn't 
it be enough to check that the correct intrinsics are generated?


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D118259/new/

https://reviews.llvm.org/D118259

___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D117898: [Clang] Add elementwise saturated add/sub builtins

2022-01-28 Thread Florian Hahn via Phabricator via cfe-commits
fhahn added inline comments.



Comment at: clang/test/CodeGen/builtins-elementwise-math.c:117
+  // CHECK-NEXT: call <4 x i32> @llvm.usub.sat.v4i32(<4 x i32> [[VU1]], <4 x 
i32> [[VU2]])
+  vu1 = __builtin_elementwise_sub_sat(vu1, vu2);
+

It might be good to have tests where one argument is signed and the other 
unsigned as well. Those appear to be missing for other builtins as well 
unfortunately.


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D117898/new/

https://reviews.llvm.org/D117898

___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D118464: [Sema] Add signed/unsigned integer mismatch tests for min/max elementwise builtins

2022-01-28 Thread Florian Hahn via Phabricator via cfe-commits
fhahn added a comment.

LGTM, thanks!


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D118464/new/

https://reviews.llvm.org/D118464

___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D115231: [Clang] Add __builtin_reduce_xor

2021-12-21 Thread Florian Hahn via Phabricator via cfe-commits
fhahn added a comment.

In D115231#3197112 , @junaire wrote:

> Thanks for accepting this patch! I would appreciate it if someone is willing 
> to commit this for me since I don't have commit access ;D
>
> You can use:
> Jun Zhang 
> j...@junz.org

It looks like the patch doesn't apply cleanly on current main. Could you rebase 
the patch?


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D115231/new/

https://reviews.llvm.org/D115231

___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D115429: [Clang] Implement the rest of __builtin_elementwise_* functions.

2021-12-21 Thread Florian Hahn via Phabricator via cfe-commits
fhahn added a comment.

In D115429#3201713 , @junaire wrote:

> Hi, @aaron.ballman  I'm sorry for not updating the patch in time because I'm 
> preparing for my school final exam :-(
> One thing I want to mention is that `__builtin_elementwise_roundeven` is 
> actually been added in the RFC during the code review. You can find it in 
> D111529 .
>
>> "Prevailing rounding mode" is not super-useful, other than as a spelling for 
>> round-to-nearest-ties-to-even (IEEE 754 default rounding). Outside of a 
>> FENV_ACCESS ON context, there's not even really a notion of "prevailing 
>> rounding mode" to appeal to. I assume the intent is for this to lower to 
>> e.g. x86 ROUND* with the dynamic rounding-mode immediate.
>>
>> I would recommend adding __builtin_elementwise_roundeven(T x) instead, which 
>> would statically bind IEEE default rounding (following TS 18661-1 naming) 
>> without having to appeal to prevailing rounding mode, and can still lower to 
>> ROUND* on x86 outside of FENV_ACCESS ON contexts, which is the norm for 
>> vector code (and FRINTN unconditionally on armv8). I think we can punt on 
>> rint/nearbyint for now, and add them in the future if there's a need.

Yes, this was a change from the RFC after some feedback to the patch.




Comment at: clang/lib/CodeGen/CGBuiltin.cpp:3137-3160
   case Builtin::BI__builtin_elementwise_ceil: {
 Value *Op0 = EmitScalarExpr(E->getArg(0));
 Value *Result = Builder.CreateUnaryIntrinsic(llvm::Intrinsic::ceil, Op0,
  nullptr, "elt.ceil");
 return RValue::get(Result);
   }
+  case Builtin::BI__builtin_elementwise_floor: {

aaron.ballman wrote:
> It's starting to seem like we should have a helper function that takes the 
> intrinsic to create and the name to give the operation; WDYT?
Sounds good! Might be good to split the `emitUnaryBuiltin` changes off into a 
separate change?


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D115429/new/

https://reviews.llvm.org/D115429

___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D115231: [Clang] Add __builtin_reduce_xor

2021-12-22 Thread Florian Hahn via Phabricator via cfe-commits
This revision was landed with ongoing or failed builds.
This revision was automatically updated to reflect the committed changes.
Closed by commit rGb55ea2fbc0a0: [Clang] Add __builtin_reduce_xor (authored by 
junaire, committed by fhahn).

Changed prior to commit:
  https://reviews.llvm.org/D115231?vs=395791&id=395814#toc

Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D115231/new/

https://reviews.llvm.org/D115231

Files:
  clang/include/clang/Basic/Builtins.def
  clang/include/clang/Basic/DiagnosticSemaKinds.td
  clang/include/clang/Sema/Sema.h
  clang/lib/CodeGen/CGBuiltin.cpp
  clang/lib/Sema/SemaChecking.cpp
  clang/test/CodeGen/builtins-reduction-math.c
  clang/test/Sema/builtins-reduction-math.c

Index: clang/test/Sema/builtins-reduction-math.c
===
--- clang/test/Sema/builtins-reduction-math.c
+++ clang/test/Sema/builtins-reduction-math.c
@@ -35,3 +35,20 @@
   i = __builtin_reduce_min(i);
   // expected-error@-1 {{1st argument must be a vector type (was 'int')}}
 }
+
+void test_builtin_reduce_xor(int i, float4 v, int3 iv) {
+  struct Foo s = __builtin_reduce_xor(iv);
+  // expected-error@-1 {{initializing 'struct Foo' with an expression of incompatible type 'int'}}
+
+  i = __builtin_reduce_xor();
+  // expected-error@-1 {{too few arguments to function call, expected 1, have 0}}
+
+  i = __builtin_reduce_xor(iv, iv);
+  // expected-error@-1 {{too many arguments to function call, expected 1, have 2}}
+
+  i = __builtin_reduce_xor(i);
+  // expected-error@-1 {{1st argument must be a vector of integers (was 'int')}}
+
+  i = __builtin_reduce_xor(v);
+  // expected-error@-1 {{1st argument must be a vector of integers (was 'float4' (vector of 4 'float' values))}}
+}
Index: clang/test/CodeGen/builtins-reduction-math.c
===
--- clang/test/CodeGen/builtins-reduction-math.c
+++ clang/test/CodeGen/builtins-reduction-math.c
@@ -57,3 +57,14 @@
   const si8 cvi1 = vi1;
   unsigned long long r5 = __builtin_reduce_min(cvi1);
 }
+
+void test_builtin_reduce_xor(si8 vi1, u4 vu1) {
+
+  // CHECK:  [[VI1:%.+]] = load <8 x i16>, <8 x i16>* %vi1.addr, align 16
+  // CHECK-NEXT: call i16 @llvm.vector.reduce.xor.v8i16(<8 x i16> [[VI1]])
+  short r2 = __builtin_reduce_xor(vi1);
+
+  // CHECK:  [[VU1:%.+]] = load <4 x i32>, <4 x i32>* %vu1.addr, align 16
+  // CHECK-NEXT: call i32 @llvm.vector.reduce.xor.v4i32(<4 x i32> [[VU1]])
+  unsigned r3 = __builtin_reduce_xor(vu1);
+}
Index: clang/lib/Sema/SemaChecking.cpp
===
--- clang/lib/Sema/SemaChecking.cpp
+++ clang/lib/Sema/SemaChecking.cpp
@@ -2216,10 +2216,38 @@
   return ExprError();
 break;
   case Builtin::BI__builtin_reduce_max:
-  case Builtin::BI__builtin_reduce_min:
-if (SemaBuiltinReduceMath(TheCall))
+  case Builtin::BI__builtin_reduce_min: {
+if (PrepareBuiltinReduceMathOneArgCall(TheCall))
   return ExprError();
+
+const Expr *Arg = TheCall->getArg(0);
+const auto *TyA = Arg->getType()->getAs();
+if (!TyA) {
+  Diag(Arg->getBeginLoc(), diag::err_builtin_invalid_arg_type)
+  << 1 << /* vector ty*/ 4 << Arg->getType();
+  return ExprError();
+}
+
+TheCall->setType(TyA->getElementType());
 break;
+  }
+
+  // __builtin_reduce_xor supports vector of integers only.
+  case Builtin::BI__builtin_reduce_xor: {
+if (PrepareBuiltinReduceMathOneArgCall(TheCall))
+  return ExprError();
+
+const Expr *Arg = TheCall->getArg(0);
+const auto *TyA = Arg->getType()->getAs();
+if (!TyA || !TyA->getElementType()->isIntegerType()) {
+  Diag(Arg->getBeginLoc(), diag::err_builtin_invalid_arg_type)
+  << 1  << /* vector of integers */ 6 << Arg->getType();
+  return ExprError();
+}
+TheCall->setType(TyA->getElementType());
+break;
+  }
+
   case Builtin::BI__builtin_matrix_transpose:
 return SemaBuiltinMatrixTranspose(TheCall, TheCallResult);
 
@@ -16882,7 +16910,7 @@
   return false;
 }
 
-bool Sema::SemaBuiltinReduceMath(CallExpr *TheCall) {
+bool Sema::PrepareBuiltinReduceMathOneArgCall(CallExpr *TheCall) {
   if (checkArgCount(*this, TheCall, 1))
 return true;
 
@@ -16891,14 +16919,6 @@
 return true;
 
   TheCall->setArg(0, A.get());
-  const VectorType *TyA = A.get()->getType()->getAs();
-  if (!TyA) {
-SourceLocation ArgLoc = TheCall->getArg(0)->getBeginLoc();
-return Diag(ArgLoc, diag::err_builtin_invalid_arg_type)
-   << 1 << /* vector ty*/ 4 << A.get()->getType();
-  }
-
-  TheCall->setType(TyA->getElementType());
   return false;
 }
 
Index: clang/lib/CodeGen/CGBuiltin.cpp
===
--- clang/lib/CodeGen/CGBuiltin.cpp
+++ clang/lib/CodeGen/CGBuiltin.cpp
@@ -3211,6 +3211,13 @@
 return RValue::get(Result);
   }
 
+  case Builtin::BI__builtin_reduc

[PATCH] D116161: [Clang] Add an overload for emitUnaryBuiltin.

2021-12-22 Thread Florian Hahn via Phabricator via cfe-commits
fhahn added a comment.

Can you also update the existing places that could use it?


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D116161/new/

https://reviews.llvm.org/D116161

___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D116161: [Clang] Add an overload for emitUnaryBuiltin.

2021-12-22 Thread Florian Hahn via Phabricator via cfe-commits
fhahn added a comment.

In D116161#3206442 , @junaire wrote:

> Update the existing place that can use `emitUnaryBuiltin`.

I meant just update the existing uses *without* adding `floor`, `roundeven`, 
`trunc`, so this change should be NFC (non-functional change)


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D116161/new/

https://reviews.llvm.org/D116161

___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D116161: [Clang] Add an overload for emitUnaryBuiltin.

2021-12-24 Thread Florian Hahn via Phabricator via cfe-commits
fhahn added inline comments.



Comment at: clang/lib/CodeGen/CGBuiltin.cpp:3137
 else
   Result = Builder.CreateUnaryIntrinsic(llvm::Intrinsic::fabs, Op0, 
nullptr,
 "elt.abs");

Should also be used here?



Comment at: clang/lib/CodeGen/CGBuiltin.cpp:3193
 Value *Op0 = EmitScalarExpr(E->getArg(0));
 Value *Result = Builder.CreateUnaryIntrinsic(
 GetIntrinsicID(E->getArg(0)->getType(), Op0->getType()), Op0, nullptr,

Should also be used here?




Comment at: clang/lib/CodeGen/CGBuiltin.cpp:3212
 Value *Op0 = EmitScalarExpr(E->getArg(0));
 Value *Result = Builder.CreateUnaryIntrinsic(
 GetIntrinsicID(E->getArg(0)->getType(), Op0->getType()), Op0, nullptr,

Should also be used here?



Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D116161/new/

https://reviews.llvm.org/D116161

___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D116161: [Clang] Add an overload for emitUnaryBuiltin.

2021-12-24 Thread Florian Hahn via Phabricator via cfe-commits
fhahn added a comment.

In D116161#3209286 , @junaire wrote:

>   35:  %0 = load float, float* %f1.addr, align 4 
>   36:  %1 = load float, float* %f1.addr, align 4 
>   37:  %elt.abs = call float @llvm.fabs.f32(float %1) 

It looks like the argument expression is evaluated twice. Did you remove the `  
  Value *Op0 = EmitScalarExpr(E->getArg(0));` calls?


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D116161/new/

https://reviews.llvm.org/D116161

___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D116161: [Clang] Add an overload for emitUnaryBuiltin.

2021-12-28 Thread Florian Hahn via Phabricator via cfe-commits
fhahn added a comment.

In D116161#3211178 , @junaire wrote:

> In order to use `emitUnaryBuiltin` in other cases, I changed the function 
> interface.
> This allows us to use it in all `Builder.CreateUnaryIntrinsic()` cases, but 
> will make
> the function body very small.

I think we should extend & use the existing `emitUnaryBuiltin`. I think in most 
cases where it cannot be used straight away you should be able to slightly 
rewrite the existing code to not rely on `llvm::Type`. Then there should be no 
need to call `EmitScalarExpr` early (an example is in the inline comments)




Comment at: clang/lib/CodeGen/CGBuiltin.cpp:535
 // matching the argument type.
 static Value *emitUnaryBuiltin(CodeGenFunction &CGF,
const CallExpr *E,

I think we should extend this `emitUnaryBuiltin` function, rather than having a 
second one.

e.g.

```
 static Value *emitUnaryBuiltin(CodeGenFunction &CGF,
const CallExpr *E,
-   unsigned IntrinsicID) {
+   unsigned IntrinsicID, llvm::StringRef Name = 
"") {
   llvm::Value *Src0 = CGF.EmitScalarExpr(E->getArg(0));

   Function *F = CGF.CGM.getIntrinsic(IntrinsicID, Src0->getType());
-  return CGF.Builder.CreateCall(F, Src0);
+  return CGF.Builder.CreateCall(F, Src0, Name);
+}
```



Comment at: clang/lib/CodeGen/CGBuiltin.cpp:3190
 };
 Value *Op0 = EmitScalarExpr(E->getArg(0));
+return RValue::get(emitUnaryBuiltin(

IICU the only reason to call `EmitScalarExpr` early is the use in 
`GetIntrinsicID`, but it could solely rely on `QualType`:


```
-auto GetIntrinsicID = [](QualType QT, llvm::Type *IrTy) {
-  if (IrTy->isIntOrIntVectorTy()) {
-if (auto *VecTy = QT->getAs())
-  QT = VecTy->getElementType();
-if (QT->isSignedIntegerType())
-  return llvm::Intrinsic::vector_reduce_smax;
-else
-  return llvm::Intrinsic::vector_reduce_umax;
-  }
+auto GetIntrinsicID = [](QualType QT) {
+  if (auto *VecTy = QT->getAs())
+QT = VecTy->getElementType();
+  if (QT->isSignedIntegerType())
+return llvm::Intrinsic::vector_reduce_smax;
+  if (QT->isUnsignedIntegerType())
+return llvm::Intrinsic::vector_reduce_umax;
+  assert(QT->isFloatingType() && "must have a float here");
   return llvm::Intrinsic::vector_reduce_fmax;
 };
```


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D116161/new/

https://reviews.llvm.org/D116161

___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D116161: [Clang] Extend emitUnaryBuiltin to avoid duplicate logic.

2022-01-02 Thread Florian Hahn via Phabricator via cfe-commits
fhahn accepted this revision.
fhahn added a comment.
This revision is now accepted and ready to land.

LGTM, thanks!


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D116161/new/

https://reviews.llvm.org/D116161

___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D116161: [Clang] Extend emitUnaryBuiltin to avoid duplicate logic.

2022-01-04 Thread Florian Hahn via Phabricator via cfe-commits
fhahn added a comment.

@junaire please let me know if you want me to land this on your behalf.


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D116161/new/

https://reviews.llvm.org/D116161

___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D116161: [Clang] Extend emitUnaryBuiltin to avoid duplicate logic.

2022-01-04 Thread Florian Hahn via Phabricator via cfe-commits
This revision was landed with ongoing or failed builds.
This revision was automatically updated to reflect the committed changes.
Closed by commit rG5c57e6aa5777: [Clang] Extend emitUnaryBuiltin to avoid 
duplicate logic. (authored by junaire, committed by fhahn).

Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D116161/new/

https://reviews.llvm.org/D116161

Files:
  clang/lib/CodeGen/CGBuiltin.cpp

Index: clang/lib/CodeGen/CGBuiltin.cpp
===
--- clang/lib/CodeGen/CGBuiltin.cpp
+++ clang/lib/CodeGen/CGBuiltin.cpp
@@ -532,13 +532,13 @@
 
 // Emit a simple mangled intrinsic that has 1 argument and a return type
 // matching the argument type.
-static Value *emitUnaryBuiltin(CodeGenFunction &CGF,
-   const CallExpr *E,
-   unsigned IntrinsicID) {
+static Value *emitUnaryBuiltin(CodeGenFunction &CGF, const CallExpr *E,
+   unsigned IntrinsicID,
+   llvm::StringRef Name = "") {
   llvm::Value *Src0 = CGF.EmitScalarExpr(E->getArg(0));
 
   Function *F = CGF.CGM.getIntrinsic(IntrinsicID, Src0->getType());
-  return CGF.Builder.CreateCall(F, Src0);
+  return CGF.Builder.CreateCall(F, Src0, Name);
 }
 
 // Emit an intrinsic that has 2 operands of the same type as its result.
@@ -3122,24 +3122,25 @@
   }
 
   case Builtin::BI__builtin_elementwise_abs: {
-Value *Op0 = EmitScalarExpr(E->getArg(0));
 Value *Result;
-if (Op0->getType()->isIntOrIntVectorTy())
+QualType QT = E->getArg(0)->getType();
+
+if (auto *VecTy = QT->getAs())
+  QT = VecTy->getElementType();
+if (QT->isIntegerType())
   Result = Builder.CreateBinaryIntrinsic(
-  llvm::Intrinsic::abs, Op0, Builder.getFalse(), nullptr, "elt.abs");
+  llvm::Intrinsic::abs, EmitScalarExpr(E->getArg(0)),
+  Builder.getFalse(), nullptr, "elt.abs");
 else
-  Result = Builder.CreateUnaryIntrinsic(llvm::Intrinsic::fabs, Op0, nullptr,
-"elt.abs");
-return RValue::get(Result);
-  }
+  Result = emitUnaryBuiltin(*this, E, llvm::Intrinsic::fabs, "elt.abs");
 
-  case Builtin::BI__builtin_elementwise_ceil: {
-Value *Op0 = EmitScalarExpr(E->getArg(0));
-Value *Result = Builder.CreateUnaryIntrinsic(llvm::Intrinsic::ceil, Op0,
- nullptr, "elt.ceil");
 return RValue::get(Result);
   }
 
+  case Builtin::BI__builtin_elementwise_ceil:
+return RValue::get(
+emitUnaryBuiltin(*this, E, llvm::Intrinsic::ceil, "elt.ceil"));
+
   case Builtin::BI__builtin_elementwise_max: {
 Value *Op0 = EmitScalarExpr(E->getArg(0));
 Value *Op1 = EmitScalarExpr(E->getArg(1));
@@ -3174,50 +3175,40 @@
   }
 
   case Builtin::BI__builtin_reduce_max: {
-auto GetIntrinsicID = [](QualType QT, llvm::Type *IrTy) {
-  if (IrTy->isIntOrIntVectorTy()) {
-if (auto *VecTy = QT->getAs())
-  QT = VecTy->getElementType();
-if (QT->isSignedIntegerType())
-  return llvm::Intrinsic::vector_reduce_smax;
-else
-  return llvm::Intrinsic::vector_reduce_umax;
-  }
+auto GetIntrinsicID = [](QualType QT) {
+  if (auto *VecTy = QT->getAs())
+QT = VecTy->getElementType();
+  if (QT->isSignedIntegerType())
+return llvm::Intrinsic::vector_reduce_smax;
+  if (QT->isUnsignedIntegerType())
+return llvm::Intrinsic::vector_reduce_umax;
+  assert(QT->isFloatingType() && "must have a float here");
   return llvm::Intrinsic::vector_reduce_fmax;
 };
-Value *Op0 = EmitScalarExpr(E->getArg(0));
-Value *Result = Builder.CreateUnaryIntrinsic(
-GetIntrinsicID(E->getArg(0)->getType(), Op0->getType()), Op0, nullptr,
-"rdx.min");
-return RValue::get(Result);
+return RValue::get(emitUnaryBuiltin(
+*this, E, GetIntrinsicID(E->getArg(0)->getType()), "rdx.min"));
   }
 
   case Builtin::BI__builtin_reduce_min: {
-auto GetIntrinsicID = [](QualType QT, llvm::Type *IrTy) {
-  if (IrTy->isIntOrIntVectorTy()) {
-if (auto *VecTy = QT->getAs())
-  QT = VecTy->getElementType();
-if (QT->isSignedIntegerType())
-  return llvm::Intrinsic::vector_reduce_smin;
-else
-  return llvm::Intrinsic::vector_reduce_umin;
-  }
+auto GetIntrinsicID = [](QualType QT) {
+  if (auto *VecTy = QT->getAs())
+QT = VecTy->getElementType();
+  if (QT->isSignedIntegerType())
+return llvm::Intrinsic::vector_reduce_smin;
+  if (QT->isUnsignedIntegerType())
+return llvm::Intrinsic::vector_reduce_umin;
+  assert(QT->isFloatingType() && "must have a float here");
   return llvm::Intrinsic::vector_reduce_fmin;
 };
-Value *Op0 = EmitScalarExpr(E->getArg(0));
-Value *Result = Builder.CreateUnaryIntrinsic(
-GetIntrin

[PATCH] D115429: [Clang] Implement the rest of __builtin_elementwise_* functions.

2022-01-04 Thread Florian Hahn via Phabricator via cfe-commits
fhahn added a comment.

This now needs a rebase after landing 5c57e6aa5777 
, then it 
should be good to go.


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D115429/new/

https://reviews.llvm.org/D115429

___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D116161: [Clang] Extend emitUnaryBuiltin to avoid duplicate logic.

2022-01-04 Thread Florian Hahn via Phabricator via cfe-commits
fhahn added a comment.

In D116161#3219149 , @junaire wrote:

> In D116161#3219080 , @fhahn wrote:
>
>> @junaire please let me know if you want me to land this on your behalf.
>
> Yeah, thanks a lot!
>
> You can use:
> Jun Zhang
> j...@junz.org

Committed! After D115429 , I'd recommend you 
obtain commit access 
https://llvm.org/docs/DeveloperPolicy.html#obtaining-commit-access


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D116161/new/

https://reviews.llvm.org/D116161

___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D115429: [Clang] Implement the rest of __builtin_elementwise_* functions.

2022-01-04 Thread Florian Hahn via Phabricator via cfe-commits
fhahn added a comment.

In D115429#3219395 , @junaire wrote:

> In D115429#3219338 , @fhahn wrote:
>
>> This now needs a rebase after landing 5c57e6aa5777 
>> , then 
>> it should be good to go.
>
> Well, I just found that you seem to have committed under the wrong name...
> My name is Jun Zhang, not Jun Zhan...
> But I think it's fine. :)

I am sorry for the typo! I reverted & recommitted the patch with the hopefully 
correct name now :)


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D115429/new/

https://reviews.llvm.org/D115429

___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D115429: [Clang] Implement the rest of __builtin_elementwise_* functions.

2022-01-04 Thread Florian Hahn via Phabricator via cfe-commits
fhahn accepted this revision.
fhahn added a comment.
This revision is now accepted and ready to land.

LGTM, thanks!


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D115429/new/

https://reviews.llvm.org/D115429

___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D115429: [Clang] Implement the rest of __builtin_elementwise_* functions.

2022-01-07 Thread Florian Hahn via Phabricator via cfe-commits
This revision was landed with ongoing or failed builds.
This revision was automatically updated to reflect the committed changes.
Closed by commit rGb2ed9f3f44d0: [Clang] Implement the rest of 
__builtin_elementwise_* functions. (authored by junaire, committed by fhahn).

Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D115429/new/

https://reviews.llvm.org/D115429

Files:
  clang/include/clang/Basic/Builtins.def
  clang/lib/CodeGen/CGBuiltin.cpp
  clang/lib/Sema/SemaChecking.cpp
  clang/test/CodeGen/builtins-elementwise-math.c
  clang/test/Sema/builtins-elementwise-math.c

Index: clang/test/Sema/builtins-elementwise-math.c
===
--- clang/test/Sema/builtins-elementwise-math.c
+++ clang/test/Sema/builtins-elementwise-math.c
@@ -156,3 +156,66 @@
   uv = __builtin_elementwise_ceil(uv);
   // expected-error@-1 {{1st argument must be a floating point type (was 'unsigned4' (vector of 4 'unsigned int' values))}}
 }
+
+void test_builtin_elementwise_floor(int i, float f, double d, float4 v, int3 iv, unsigned u, unsigned4 uv) {
+
+  struct Foo s = __builtin_elementwise_floor(f);
+  // expected-error@-1 {{initializing 'struct Foo' with an expression of incompatible type 'float'}}
+
+  i = __builtin_elementwise_floor();
+  // expected-error@-1 {{too few arguments to function call, expected 1, have 0}}
+
+  i = __builtin_elementwise_floor(i);
+  // expected-error@-1 {{1st argument must be a floating point type (was 'int')}}
+
+  i = __builtin_elementwise_floor(f, f);
+  // expected-error@-1 {{too many arguments to function call, expected 1, have 2}}
+
+  u = __builtin_elementwise_floor(u);
+  // expected-error@-1 {{1st argument must be a floating point type (was 'unsigned int')}}
+
+  uv = __builtin_elementwise_floor(uv);
+  // expected-error@-1 {{1st argument must be a floating point type (was 'unsigned4' (vector of 4 'unsigned int' values))}}
+}
+
+void test_builtin_elementwise_roundeven(int i, float f, double d, float4 v, int3 iv, unsigned u, unsigned4 uv) {
+
+  struct Foo s = __builtin_elementwise_roundeven(f);
+  // expected-error@-1 {{initializing 'struct Foo' with an expression of incompatible type 'float'}}
+
+  i = __builtin_elementwise_roundeven();
+  // expected-error@-1 {{too few arguments to function call, expected 1, have 0}}
+
+  i = __builtin_elementwise_roundeven(i);
+  // expected-error@-1 {{1st argument must be a floating point type (was 'int')}}
+
+  i = __builtin_elementwise_roundeven(f, f);
+  // expected-error@-1 {{too many arguments to function call, expected 1, have 2}}
+
+  u = __builtin_elementwise_roundeven(u);
+  // expected-error@-1 {{1st argument must be a floating point type (was 'unsigned int')}}
+
+  uv = __builtin_elementwise_roundeven(uv);
+  // expected-error@-1 {{1st argument must be a floating point type (was 'unsigned4' (vector of 4 'unsigned int' values))}}
+}
+
+void test_builtin_elementwise_trunc(int i, float f, double d, float4 v, int3 iv, unsigned u, unsigned4 uv) {
+
+  struct Foo s = __builtin_elementwise_trunc(f);
+  // expected-error@-1 {{initializing 'struct Foo' with an expression of incompatible type 'float'}}
+
+  i = __builtin_elementwise_trunc();
+  // expected-error@-1 {{too few arguments to function call, expected 1, have 0}}
+
+  i = __builtin_elementwise_trunc(i);
+  // expected-error@-1 {{1st argument must be a floating point type (was 'int')}}
+
+  i = __builtin_elementwise_trunc(f, f);
+  // expected-error@-1 {{too many arguments to function call, expected 1, have 2}}
+
+  u = __builtin_elementwise_trunc(u);
+  // expected-error@-1 {{1st argument must be a floating point type (was 'unsigned int')}}
+
+  uv = __builtin_elementwise_trunc(uv);
+  // expected-error@-1 {{1st argument must be a floating point type (was 'unsigned4' (vector of 4 'unsigned int' values))}}
+}
Index: clang/test/CodeGen/builtins-elementwise-math.c
===
--- clang/test/CodeGen/builtins-elementwise-math.c
+++ clang/test/CodeGen/builtins-elementwise-math.c
@@ -205,3 +205,51 @@
   // CHECK-NEXT: call <4 x float> @llvm.ceil.v4f32(<4 x float> [[VF1]])
   vf2 = __builtin_elementwise_ceil(vf1);
 }
+
+void test_builtin_elementwise_floor(float f1, float f2, double d1, double d2,
+float4 vf1, float4 vf2) {
+  // CHECK-LABEL: define void @test_builtin_elementwise_floor(
+  // CHECK:  [[F1:%.+]] = load float, float* %f1.addr, align 4
+  // CHECK-NEXT:  call float @llvm.floor.f32(float [[F1]])
+  f2 = __builtin_elementwise_floor(f1);
+
+  // CHECK:  [[D1:%.+]] = load double, double* %d1.addr, align 8
+  // CHECK-NEXT: call double @llvm.floor.f64(double [[D1]])
+  d2 = __builtin_elementwise_floor(d1);
+
+  // CHECK:  [[VF1:%.+]] = load <4 x float>, <4 x float>* %vf1.addr, align 16
+  // CHECK-NEXT: call <4 x float> @llvm.floor.v4f32(<4 x float> [[VF1]])
+  vf2 = __builtin_elementwise_flo

[PATCH] D116736: [Clang] Add __builtin_reduce_or and __builtin_reduce_and

2022-01-09 Thread Florian Hahn via Phabricator via cfe-commits
fhahn added reviewers: aaron.ballman, erichkeane.
fhahn added a comment.

LGTM, thanks!

> The last __builtin_reduce_add will be seperated into another one.

Are you planning on putting up a patch for this one as well? What makes add a 
bit different is that `‘llvm.vector.reduce.fadd.*’` can only perform reductions 
either in the original order or in an unspecified order. For the extension, we 
need a particular evaluation order (reduction tree adding adjacent element 
pairs). Technically this order is required for all reduction builtins, but for 
integers the order doesn't matter, same for min/max.




Comment at: clang/lib/Sema/SemaChecking.cpp:2235
 
-  // __builtin_reduce_xor supports vector of integers only.
-  case Builtin::BI__builtin_reduce_xor: {
+  // This builtins support vector of integers only.
+  case Builtin::BI__builtin_reduce_xor:

nit: Those  vectors 


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D116736/new/

https://reviews.llvm.org/D116736

___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D116935: [IRBuilder] Introduce folder using inst-simplify, use for Or fold.

2022-01-11 Thread Florian Hahn via Phabricator via cfe-commits
fhahn added a comment.

In D116935#3232763 , @craig.topper 
wrote:

> Do the programs in compile-time tracker make much use of bitfields?

I'd expect some bitfields, but nothing excessive/pathological.

> Is there any indication in rdar://7362516 what program needed this? It looks 
> like assigning a bitfield to 0 is enough to generate an or with 0 that 
> survives through fast isel at -O0 on X86. But a few assignments to 0 wouldn't 
> make for a huge problem, so I imagine there must have been something 
> pathological about some program.

I had a look at  rdar://7362516 and there is nothing in the issue & history 
that seems to indicate that the motivation was a pathological case, but just a 
very simple struct with 4 bitfields. Clang generates a lot of other redundant 
IR that doesn't get folded by IRBuilder (e.g. add or shifts of 0), which 
survive in a similar way with fast isel. AFAICT there's nothing that would 
indicate that `or X, 0` is a special case that would warrant special treatment. 
 rdar://7362516  also mentions that IRBuilder should fold shifts with 0 as 
well, but it looks like that's not happening at the moment either.

I am inclined to remove the special case from IRBuilder, which applies the 
'IRBuilder should not optimize directly, only via a specified folder' policy 
also to `CreateOr`. I don't think we should use InstSimplifyFolder in Clang, 
because Clang usually doesn't try very hard to optimize IR and 
InstructionSimplify provides a lot of folds. But if we get additional feedback 
after the commit that the `or X, 0` fold is very valuable for Clang, this can 
be provided to Clang via a custom ClangFolder.


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D116935/new/

https://reviews.llvm.org/D116935

___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D116919: [AST] Add RParen loc for decltype AutoTypeloc.

2022-01-12 Thread Florian Hahn via Phabricator via cfe-commits
fhahn added a comment.

In D116919#3236899 , @mstorsjo wrote:

> The relanded version in rG41fbdfa4d5601cccbcdc0ded8ef35190d502f7f3 
>  seems 
> to be breaking some builds with PCH for me, failing asserts like this:
>
>   clang: ../tools/clang/include/clang/Basic/SourceLocation.h:135: 
> clang::SourceLocation 
> clang::SourceLocation::getLocWithOffset(clang::SourceLocation::IntTy) const: 
> Assertion `((getOffset()+Offset) & MacroIDBit) == 0 && "offset overflow"' 
> failed.

This also breaks stage2 builds with debug info, e.g. 
https://green.lab.llvm.org/green/job/clang-stage2-Rthinlto/5088/console

Given that the bot has been red a while now, I reverted the commit eadb4cfeeff5 
 for now.

The crash should be reproducible when doing a stage2 build with debug info. It 
crashes, e.g. when building llvm-project/llvm/lib/Support/Timer.cpp

   
/Users/buildslave/jenkins/workspace/clang-stage2-Rthinlto/host-compiler/bin/clang++
  -DGTEST_HAS_RTTI=0 -D__STDC_CONSTANT_MACROS -D__STDC_FORMAT_MACROS 
-D__STDC_LIMIT_MACROS -Ilib/Support 
-I/Users/buildslave/jenkins/workspace/clang-stage2-Rthinlto/llvm-project/llvm/lib/Support
 -Iinclude 
-I/Users/buildslave/jenkins/workspace/clang-stage2-Rthinlto/llvm-project/llvm/include
 -fno-stack-protector -fno-common -Wno-profile-instr-unprofiled -fPIC 
-fvisibility-inlines-hidden -Werror=date-time 
-Werror=unguarded-availability-new -fmodules 
-fmodules-cache-path=/Users/buildslave/jenkins/workspace/clang-stage2-Rthinlto/clang-build/Build/module.cache
 -fcxx-modules -Xclang -fmodules-local-submodule-visibility -gmodules -Wall 
-Wextra -Wno-unused-parameter -Wwrite-strings -Wcast-qual 
-Wmissing-field-initializers -pedantic -Wno-long-long -Wc++98-compat-extra-semi 
-Wimplicit-fallthrough -Wcovered-switch-default -Wno-noexcept-type 
-Wnon-virtual-dtor -Wdelete-non-virtual-dtor -Wsuggest-override 
-Wstring-conversion -Wmisleading-indentation -fdiagnostics-color -flto=thin  
-O2 -g -DNDEBUG -isysroot 
/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.15.sdk
   -std=c++14  -fno-exceptions -fno-rtti -MD -MT 
lib/Support/CMakeFiles/LLVMSupport.dir/Timer.cpp.o -MF 
lib/Support/CMakeFiles/LLVMSupport.dir/Timer.cpp.o.d -o 
lib/Support/CMakeFiles/LLVMSupport.dir/Timer.cpp.o -c 
/Users/buildslave/jenkins/workspace/clang-stage2-Rthinlto/llvm-project/llvm/lib/Support/Timer.cpp
  Assertion failed: (((getOffset()+Offset) & MacroIDBit) == 0 && "offset 
overflow"), function getLocWithOffset, file 
/Users/buildslave/jenkins/workspace/clang-stage1-RA/llvm-project/clang/include/clang/Basic/SourceLocation.h,
 line 135.


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D116919/new/

https://reviews.llvm.org/D116919

___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D115942: [X86][MS] Change the alignment of f80 to 16 bytes on Windows 32bits to match with ICC

2022-01-12 Thread Florian Hahn via Phabricator via cfe-commits
fhahn added a comment.

It looks like this may be causing the following bot to fail 
https://lab.llvm.org/buildbot/#/builders/16/builds/22138 with

   TEST 'lld :: COFF/lto-lazy-reference.ll' FAILED 

  Script:
  --
  : 'RUN: at line 2';   
/b/1/llvm-clang-x86_64-expensive-checks-debian/build/bin/llc 
-mtriple=i686-pc-windows-msvc -filetype=obj -o 
/b/1/llvm-clang-x86_64-expensive-checks-debian/build/tools/lld/test/COFF/Output/lto-lazy-reference-quadruple.obj
 
/b/1/llvm-clang-x86_64-expensive-checks-debian/llvm-project/lld/test/COFF/Inputs/lto-lazy-reference-quadruple.ll
  : 'RUN: at line 3';   
/b/1/llvm-clang-x86_64-expensive-checks-debian/build/bin/llvm-as -o 
/b/1/llvm-clang-x86_64-expensive-checks-debian/build/tools/lld/test/COFF/Output/lto-lazy-reference-dummy.bc
 
/b/1/llvm-clang-x86_64-expensive-checks-debian/llvm-project/lld/test/COFF/Inputs/lto-lazy-reference-dummy.ll
  : 'RUN: at line 4';   rm -f 
/b/1/llvm-clang-x86_64-expensive-checks-debian/build/tools/lld/test/COFF/Output/lto-lazy-reference.ll.tmp.lib
  : 'RUN: at line 5';   llvm-ar cru 
/b/1/llvm-clang-x86_64-expensive-checks-debian/build/tools/lld/test/COFF/Output/lto-lazy-reference.ll.tmp.lib
 
/b/1/llvm-clang-x86_64-expensive-checks-debian/build/tools/lld/test/COFF/Output/lto-lazy-reference-quadruple.obj
 
/b/1/llvm-clang-x86_64-expensive-checks-debian/build/tools/lld/test/COFF/Output/lto-lazy-reference-dummy.bc
  : 'RUN: at line 6';   
/b/1/llvm-clang-x86_64-expensive-checks-debian/build/bin/llvm-as -o 
/b/1/llvm-clang-x86_64-expensive-checks-debian/build/tools/lld/test/COFF/Output/lto-lazy-reference.ll.tmp.obj
 
/b/1/llvm-clang-x86_64-expensive-checks-debian/llvm-project/lld/test/COFF/lto-lazy-reference.ll
  : 'RUN: at line 7';   
/b/1/llvm-clang-x86_64-expensive-checks-debian/build/bin/lld-link 
/out:/b/1/llvm-clang-x86_64-expensive-checks-debian/build/tools/lld/test/COFF/Output/lto-lazy-reference.ll.tmp.exe
 /entry:main /subsystem:console 
/b/1/llvm-clang-x86_64-expensive-checks-debian/build/tools/lld/test/COFF/Output/lto-lazy-reference.ll.tmp.obj
 
/b/1/llvm-clang-x86_64-expensive-checks-debian/build/tools/lld/test/COFF/Output/lto-lazy-reference.ll.tmp.lib
  --
  Exit Code: 134
  Command Output (stderr):
  --
  + : 'RUN: at line 2'
  + /b/1/llvm-clang-x86_64-expensive-checks-debian/build/bin/llc 
-mtriple=i686-pc-windows-msvc -filetype=obj -o 
/b/1/llvm-clang-x86_64-expensive-checks-debian/build/tools/lld/test/COFF/Output/lto-lazy-reference-quadruple.obj
 
/b/1/llvm-clang-x86_64-expensive-checks-debian/llvm-project/lld/test/COFF/Inputs/lto-lazy-reference-quadruple.ll
  + : 'RUN: at line 3'
  + /b/1/llvm-clang-x86_64-expensive-checks-debian/build/bin/llvm-as -o 
/b/1/llvm-clang-x86_64-expensive-checks-debian/build/tools/lld/test/COFF/Output/lto-lazy-reference-dummy.bc
 
/b/1/llvm-clang-x86_64-expensive-checks-debian/llvm-project/lld/test/COFF/Inputs/lto-lazy-reference-dummy.ll
  + : 'RUN: at line 4'
  + rm -f 
/b/1/llvm-clang-x86_64-expensive-checks-debian/build/tools/lld/test/COFF/Output/lto-lazy-reference.ll.tmp.lib
  + : 'RUN: at line 5'
  + llvm-ar cru 
/b/1/llvm-clang-x86_64-expensive-checks-debian/build/tools/lld/test/COFF/Output/lto-lazy-reference.ll.tmp.lib
 
/b/1/llvm-clang-x86_64-expensive-checks-debian/build/tools/lld/test/COFF/Output/lto-lazy-reference-quadruple.obj
 
/b/1/llvm-clang-x86_64-expensive-checks-debian/build/tools/lld/test/COFF/Output/lto-lazy-reference-dummy.bc
  + : 'RUN: at line 6'
  + /b/1/llvm-clang-x86_64-expensive-checks-debian/build/bin/llvm-as -o 
/b/1/llvm-clang-x86_64-expensive-checks-debian/build/tools/lld/test/COFF/Output/lto-lazy-reference.ll.tmp.obj
 
/b/1/llvm-clang-x86_64-expensive-checks-debian/llvm-project/lld/test/COFF/lto-lazy-reference.ll
  + : 'RUN: at line 7'
  + /b/1/llvm-clang-x86_64-expensive-checks-debian/build/bin/lld-link 
/out:/b/1/llvm-clang-x86_64-expensive-checks-debian/build/tools/lld/test/COFF/Output/lto-lazy-reference.ll.tmp.exe
 /entry:main /subsystem:console 
/b/1/llvm-clang-x86_64-expensive-checks-debian/build/tools/lld/test/COFF/Output/lto-lazy-reference.ll.tmp.obj
 
/b/1/llvm-clang-x86_64-expensive-checks-debian/build/tools/lld/test/COFF/Output/lto-lazy-reference.ll.tmp.lib
  lld-link: 
/b/1/llvm-clang-x86_64-expensive-checks-debian/llvm-project/llvm/lib/CodeGen/MachineFunction.cpp:207:
 void llvm::MachineFunction::init(): Assertion 
`Target.isCompatibleDataLayout(getDataLayout()) && "Can't create a 
MachineFunction using a Module with a " "Target-incompatible DataLayout 
attached\n"' failed.
  
/b/1/llvm-clang-x86_64-expensive-checks-debian/build/tools/lld/test/COFF/Output/lto-lazy-reference.ll.script:
 line 6: 2469401 Aborted 
/b/1/llvm-clang-x86_64-expensive-checks-debian/build/bin/lld-link 
/out:/b/1/llvm-clang-x86_64-expensive-checks-debian/build/tools/lld/test/COFF/Output/lto-lazy-reference.ll.tmp.exe
 /entry:main /subsystem:console 
/b/1/llvm-clang-x86_64-expensive-checks-debian/build/tools/lld/test/COFF/O

[PATCH] D111529: Specify Clang vector builtins.

2021-10-12 Thread Florian Hahn via Phabricator via cfe-commits
fhahn updated this revision to Diff 378992.
fhahn added a comment.

Try to be more precise about how the reduction steps are performed and replace 
_round and _rint by roundeven.


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D111529/new/

https://reviews.llvm.org/D111529

Files:
  clang/docs/LanguageExtensions.rst


Index: clang/docs/LanguageExtensions.rst
===
--- clang/docs/LanguageExtensions.rst
+++ clang/docs/LanguageExtensions.rst
@@ -506,6 +506,71 @@
   If it's an extension (OpenCL) vector, it's only available in C and OpenCL C.
   And it selects base on signedness of the condition operands (OpenCL v1.1 
s6.3.9).
 
+Vector Builtins
+---
+
+In addition to the operators mentioned above, Clang provides a set of builtins
+to perform additional operations on certain scalar and vector types.
+
+Let ``T`` be one of the following types:
+
+* an integer type (as in C2x 6.2.5p19), but excluding enumerated types and 
_Bool
+* the standard floating types float or double
+* a half-precision floating point type, if one is supported on the target
+* a vector type.
+
+For scalar types, consider the operation applied to a vector with a single 
element.
+
+*Elementwise Builtins*
+
+Each builtin returns a vector equivalent to applying the specified operation
+elementwise to the input.
+
+Unless specified otherwise operation(±0) = ±0 and operation(±infinity) = 
±infinity
+
+= 
 
==
+ Name  Operation   
 Supported element types
+= 
 
==
+ T __builtin_elementwise_abs(T x)  return the absolute value of a 
number x   integer and floating point types
+ T __builtin_elementwise_ceil(T x) return the smallest integral value 
greater than or equal to x floating point types
+ T __builtin_elementwise_floor(T x)return the largest integral value 
less than or equal to x floating point types
+ T __builtin_elementwise_roundeven(T x)round x to the nearest integer 
value in floating point format,floating point types
+   rounding halfway cases to even 
(that is, to the nearest value
+   that is an even integer), 
regardless of the current rounding
+   direction.
+ T__builtin_elementwise_trunc(T x) return the integral value nearest 
to but no larger in floating point types
+   magnitude than x
+ T __builtin_elementwise_max(T x, T y) return x or y, whichever is larger  
  integer and floating point types
+ T __builtin_elementwise_min(T x, T y) return x or y, whichever is smaller 
  integer and floating point types
+= 
 
==
+
+
+*Reduction Builtins*
+
+Each builtin returns a scalar equivalent to applying the specified
+operation(x, y) as pairwise tree reduction to the input. In each reduction 
step,
+the vector elements of the first vector are concatenated after the elements of
+the second vector. The result vector is created by reading pairs of adjacent
+elements from the concatenated vector, applying the operation to the pair and
+placing the result in the result vector.
+
+Let ``VT`` be a vector type and ``ET`` the element type of ``VT``.
+
+=== 
 
==
+ NameOperation 
   Supported element types
+=== 
 
==
+ ET __builtin_reduce_max(VT a)   return x or y, whichever is larger; 
If exactly one argument is   integer and floating point types
+ a NaN, return the other argument. If 
both arguments are NaNs,
+ fmax() return a NaN.
+ ET __builtin_reduce_min(VT a)   return x or y, whichever is smaller; 
If exactly one argument integer and floating point types
+ is a NaN, return the other argument. 
If both arguments are
+ NaNs, fmax() return a NaN.
+ ET __builtin_reduce_add(VT a)   \+   

[PATCH] D111529: Specify Clang vector builtins.

2021-10-12 Thread Florian Hahn via Phabricator via cfe-commits
fhahn marked 4 inline comments as done.
fhahn added inline comments.



Comment at: clang/docs/LanguageExtensions.rst:538
+ T __builtin_elementwise_rint(T x)  return the integral value nearest to x 
(according to the  floating point types
+prevailing rounding mode) in 
floating-point format
+ T __builtin_elementwise_round(T x) return the integral value nearest to x 
rounding half-way casesfloating point types

scanon wrote:
> "Prevailing rounding mode" is not super-useful, other than as a spelling for 
> round-to-nearest-ties-to-even (IEEE 754 default rounding). Outside of a 
> `FENV_ACCESS ON` context, there's not even really a notion of "prevailing 
> rounding mode" to appeal to. I assume the intent is for this to lower to e.g. 
> x86 ROUND* with the dynamic rounding-mode immediate.
> 
> I would recommend adding `__builtin_elementwise_roundeven(T x)` instead, 
> which would statically bind IEEE default rounding (following TS 18661-1 
> naming) without having to appeal to prevailing rounding mode, and can still 
> lower to ROUND* on x86 outside of FENV_ACCESS ON contexts, which is the norm 
> for vector code  (and FRINTN unconditionally on armv8). I think we can punt 
> on rint/nearbyint for now, and add them in the future if there's a need.
I removed `rint` and `round` for now and add` _roundeven` with the wording from 
TS 18661-1



Comment at: clang/docs/LanguageExtensions.rst:552
+operation(x, y) as pairwise tree reduction to the input. The pairs are formed
+by concatenating both inputs and pairing adjacent elements.
+

craig.topper wrote:
> I'm not sure I understand what is being concatenated here.
I tried to spell it out more clearly. I'm still not sure if that spells it out 
as clearly as possibly and I'd appreciate any suggestions on how to improve the 
wording.


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D111529/new/

https://reviews.llvm.org/D111529

___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D111529: Specify Clang vector builtins.

2021-10-13 Thread Florian Hahn via Phabricator via cfe-commits
fhahn updated this revision to Diff 379517.
fhahn marked 2 inline comments as done.
fhahn added a comment.

Another stab at phrasing the reduction step. Also added a note that the 
implementation is work-in-progress.


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D111529/new/

https://reviews.llvm.org/D111529

Files:
  clang/docs/LanguageExtensions.rst


Index: clang/docs/LanguageExtensions.rst
===
--- clang/docs/LanguageExtensions.rst
+++ clang/docs/LanguageExtensions.rst
@@ -506,6 +506,71 @@
   If it's an extension (OpenCL) vector, it's only available in C and OpenCL C.
   And it selects base on signedness of the condition operands (OpenCL v1.1 
s6.3.9).
 
+Vector Builtins
+---
+
+**Note: The implementation of vector builtins is work-in-progress and 
incomplete.**
+
+In addition to the operators mentioned above, Clang provides a set of builtins
+to perform additional operations on certain scalar and vector types.
+
+Let ``T`` be one of the following types:
+
+* an integer type (as in C2x 6.2.5p19), but excluding enumerated types and 
_Bool
+* the standard floating types float or double
+* a half-precision floating point type, if one is supported on the target
+* a vector type.
+
+For scalar types, consider the operation applied to a vector with a single 
element.
+
+*Elementwise Builtins*
+
+Each builtin returns a vector equivalent to applying the specified operation
+elementwise to the input.
+
+Unless specified otherwise operation(±0) = ±0 and operation(±infinity) = 
±infinity
+
+= 
 
==
+ Name  Operation   
 Supported element types
+= 
 
==
+ T __builtin_elementwise_abs(T x)  return the absolute value of a 
number x   integer and floating point types
+ T __builtin_elementwise_ceil(T x) return the smallest integral value 
greater than or equal to x floating point types
+ T __builtin_elementwise_floor(T x)return the largest integral value 
less than or equal to x floating point types
+ T __builtin_elementwise_roundeven(T x)round x to the nearest integer 
value in floating point format,floating point types
+   rounding halfway cases to even 
(that is, to the nearest value
+   that is an even integer), 
regardless of the current rounding
+   direction.
+ T__builtin_elementwise_trunc(T x) return the integral value nearest 
to but no larger in floating point types
+   magnitude than x
+ T __builtin_elementwise_max(T x, T y) return x or y, whichever is larger  
  integer and floating point types
+ T __builtin_elementwise_min(T x, T y) return x or y, whichever is smaller 
  integer and floating point types
+= 
 
==
+
+
+*Reduction Builtins*
+
+Each builtin returns a scalar equivalent to applying the specified
+operation(x, y) as horizontal recursive pairwise reduction to all vector
+elements. In each reduction step, ``operation(x, y)`` is applied to adjacent
+elements.
+
+Let ``VT`` be a vector type and ``ET`` the element type of ``VT``.
+
+=== 
 
==
+ NameOperation 
   Supported element types
+=== 
 
==
+ ET __builtin_reduce_max(VT a)   return x or y, whichever is larger; 
If exactly one argument is   integer and floating point types
+ a NaN, return the other argument. If 
both arguments are NaNs,
+ fmax() return a NaN.
+ ET __builtin_reduce_min(VT a)   return x or y, whichever is smaller; 
If exactly one argument integer and floating point types
+ is a NaN, return the other argument. 
If both arguments are
+ NaNs, fmax() return a NaN.
+ ET __builtin_reduce_add(VT a)   \+
   integer and floating point types

[PATCH] D111529: Specify Clang vector builtins.

2021-10-13 Thread Florian Hahn via Phabricator via cfe-commits
fhahn marked an inline comment as done.
fhahn added inline comments.



Comment at: clang/docs/LanguageExtensions.rst:552
+operation(x, y) as pairwise tree reduction to the input. The pairs are formed
+by concatenating both inputs and pairing adjacent elements.
+

craig.topper wrote:
> fhahn wrote:
> > craig.topper wrote:
> > > I'm not sure I understand what is being concatenated here.
> > I tried to spell it out more clearly. I'm still not sure if that spells it 
> > out as clearly as possibly and I'd appreciate any suggestions on how to 
> > improve the wording.
> The input is a single vector. I'm not understanding where we get a second 
> vector to concatenate.
Oh yes, now I see where the confusion was coming from. I was thinking about the 
reduction tree and how the input is broken up. Sorry for the confusing wording. 
I gave it another try, should be much simpler again now.


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D111529/new/

https://reviews.llvm.org/D111529

___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D111985: [Clang] Add elementwise min/max builtins.

2021-10-18 Thread Florian Hahn via Phabricator via cfe-commits
fhahn created this revision.
fhahn added reviewers: aaron.ballman, scanon, craig.topper, rjmccall, 
erichkeane.
fhahn requested review of this revision.
Herald added a project: clang.

This patch implements __builtin_elementwise_max and
__builtin_elementwise_min, as specified in D111529 
.


Repository:
  rG LLVM Github Monorepo

https://reviews.llvm.org/D111985

Files:
  clang/include/clang/Basic/Builtins.def
  clang/include/clang/Basic/DiagnosticSemaKinds.td
  clang/include/clang/Sema/Sema.h
  clang/lib/CodeGen/CGBuiltin.cpp
  clang/lib/Sema/SemaChecking.cpp
  clang/test/CodeGen/builtins-elementwise-math.c
  clang/test/Sema/builtins-elementwise-math.c

Index: clang/test/Sema/builtins-elementwise-math.c
===
--- /dev/null
+++ clang/test/Sema/builtins-elementwise-math.c
@@ -0,0 +1,42 @@
+// RUN: %clang_cc1 %s -pedantic -verify -triple=x86_64-apple-darwin9
+
+typedef float float4 __attribute__((ext_vector_type(4)));
+typedef int int3 __attribute__((ext_vector_type(3)));
+
+struct Foo {
+  char *p;
+};
+
+void builtin_elementwise_max(int i, double d, float4 v, int3 iv) {
+  i = __builtin_elementwise_max(i, d);
+  // expected-error@-1 {{argument types do not match, 'int' != 'double'}}
+
+  struct Foo s = __builtin_elementwise_max(i, i);
+  // expected-error@-1 {{initializing 'struct Foo' with an expression of incompatible type 'int'}}
+
+  i = __builtin_elementwise_max(i);
+  // expected-error@-1 {{too few arguments to function call, expected 2, have 1}}
+
+  i = __builtin_elementwise_max();
+  // expected-error@-1 {{too few arguments to function call, expected 2, have 0}}
+
+  i = __builtin_elementwise_max(v, iv);
+  // expected-error@-1 {{argument types do not match, 'float4' (vector of 4 'float' values) != 'int3' (vector of 3 'int' values)}}
+}
+
+void builtin_elementwise_min(int i, double d, float4 v, int3 iv) {
+  i = __builtin_elementwise_min(i, d);
+  // expected-error@-1 {{argument types do not match, 'int' != 'double'}}
+
+  struct Foo s = __builtin_elementwise_min(i, i);
+  // expected-error@-1 {{initializing 'struct Foo' with an expression of incompatible type 'int'}}
+
+  i = __builtin_elementwise_min(i);
+  // expected-error@-1 {{too few arguments to function call, expected 2, have 1}}
+
+  i = __builtin_elementwise_min();
+  // expected-error@-1 {{too few arguments to function call, expected 2, have 0}}
+
+  i = __builtin_elementwise_min(v, iv);
+  // expected-error@-1 {{argument types do not match, 'float4' (vector of 4 'float' values) != 'int3' (vector of 3 'int' values)}}
+}
Index: clang/test/CodeGen/builtins-elementwise-math.c
===
--- /dev/null
+++ clang/test/CodeGen/builtins-elementwise-math.c
@@ -0,0 +1,85 @@
+// RUN: %clang_cc1 -disable-noundef-analysis -triple x86_64-apple-darwin %s -emit-llvm -disable-llvm-passes -o - | FileCheck %s
+
+typedef float float4 __attribute__((ext_vector_type(4)));
+typedef short int si8 __attribute__((ext_vector_type(8)));
+typedef unsigned int u4 __attribute__((ext_vector_type(4)));
+
+void builtin_max(float f1, float f2, double d1, double d2, float4 vf1,
+ float4 vf2, long long int i1, long long int i2, si8 vi1,
+ si8 vi2, unsigned u1, unsigned u2, u4 vu1, u4 vu2) {
+  // CHECK-LABEL: define void @builtin_max(
+  // CHECK:  [[F1:%.+]] = load float, float* %f1.addr, align 4
+  // CHECK-NEXT: [[F2:%.+]] = load float, float* %f2.addr, align 4
+  // CHECK-NEXT:  call float @llvm.maxnum.f32(float %0, float %1)
+  f1 = __builtin_elementwise_max(f1, f2);
+
+  // CHECK:  [[D1:%.+]] = load double, double* %d1.addr, align 8
+  // CHECK-NEXT: [[D2:%.+]] = load double, double* %d2.addr, align 8
+  // CHECK-NEXT: call double @llvm.maxnum.f64(double [[D1]], double [[D2]])
+  d1 = __builtin_elementwise_max(d1, d2);
+
+  // CHECK:  [[VF1:%.+]] = load <4 x float>, <4 x float>* %vf1.addr, align 16
+  // CHECK-NEXT: [[VF2:%.+]] = load <4 x float>, <4 x float>* %vf2.addr, align 16
+  // CHECK-NEXT: call <4 x float> @llvm.maxnum.v4f32(<4 x float> [[VF1]], <4 x float> [[VF2]])
+  vf1 = __builtin_elementwise_max(vf1, vf2);
+
+  // CHECK:  [[I1:%.+]] = load i64, i64* %i1.addr, align 8
+  // CHECK-NEXT: [[I2:%.+]] = load i64, i64* %i2.addr, align 8
+  // CHECK-NEXT: call i64 @llvm.smax.i64(i64 [[I1]], i64 [[I2]])
+  i1 = __builtin_elementwise_max(i1, i2);
+
+  // CHECK:  [[VI1:%.+]] = load <8 x i16>, <8 x i16>* %vi1.addr, align 16
+  // CHECK-NEXT: [[VI2:%.+]] = load <8 x i16>, <8 x i16>* %vi2.addr, align 16
+  // CHECK-NEXT: call <8 x i16> @llvm.smax.v8i16(<8 x i16> [[VI1]], <8 x i16> [[VI2]])
+  vi1 = __builtin_elementwise_max(vi1, vi2);
+
+  // CHECK:  [[U1:%.+]] = load i32, i32* %u1.addr, align 4
+  // CHECK-NEXT: [[U2:%.+]] = load i32, i32* %u2.addr, align 4
+  // CHECK-NEXT: call i32 @llvm.umax.i32(i32 [[U1]], i32 [[U2]])
+  u1 = __builtin_elementwise_max(u1, u2

[PATCH] D111986: [Clang] Add elementwise abs builtin.

2021-10-18 Thread Florian Hahn via Phabricator via cfe-commits
fhahn created this revision.
fhahn added reviewers: aaron.ballman, scanon, craig.topper, rjmccall, 
erichkeane.
Herald added a subscriber: mstorsjo.
fhahn requested review of this revision.
Herald added a project: clang.

This patch implements __builtin_elementwise_abs as specified in
D111529 .


Repository:
  rG LLVM Github Monorepo

https://reviews.llvm.org/D111986

Files:
  clang/include/clang/Basic/Builtins.def
  clang/include/clang/Basic/DiagnosticSemaKinds.td
  clang/include/clang/Sema/Sema.h
  clang/lib/CodeGen/CGBuiltin.cpp
  clang/lib/Sema/SemaChecking.cpp
  clang/test/CodeGen/builtins-elementwise-math.c
  clang/test/Sema/builtins-elementwise-math.c

Index: clang/test/Sema/builtins-elementwise-math.c
===
--- clang/test/Sema/builtins-elementwise-math.c
+++ clang/test/Sema/builtins-elementwise-math.c
@@ -2,11 +2,32 @@
 
 typedef float float4 __attribute__((ext_vector_type(4)));
 typedef int int3 __attribute__((ext_vector_type(3)));
+typedef unsigned unsigned4 __attribute__((ext_vector_type(4)));
 
 struct Foo {
   char *p;
 };
 
+void builtin_elementwise_abs(int i, double d, float4 v, int3 iv, unsigned u, unsigned4 uv) {
+  struct Foo s = __builtin_elementwise_abs(i);
+  // expected-error@-1 {{initializing 'struct Foo' with an expression of incompatible type 'int'}}
+
+  i = __builtin_elementwise_abs();
+  // expected-error@-1 {{too few arguments to function call, expected 1, have 0}}
+
+  i = __builtin_elementwise_abs(i, i);
+  // expected-error@-1 {{too many arguments to function call, expected 1, have 2}}
+
+  i = __builtin_elementwise_abs(v);
+  // expected-error@-1 {{assigning to 'int' from incompatible type 'float4' (vector of 4 'float' values)}}
+
+  u = __builtin_elementwise_abs(u);
+  // expected-error@-1 {{argument must have a signed integer or floating point type, but had a unsigned integer type}}
+
+  uv = __builtin_elementwise_abs(uv);
+  // expected-error@-1 {{argument must have a signed integer or floating point type, but had a unsigned integer type}}
+}
+
 void builtin_elementwise_max(int i, double d, float4 v, int3 iv) {
   i = __builtin_elementwise_max(i, d);
   // expected-error@-1 {{argument types do not match, 'int' != 'double'}}
Index: clang/test/CodeGen/builtins-elementwise-math.c
===
--- clang/test/CodeGen/builtins-elementwise-math.c
+++ clang/test/CodeGen/builtins-elementwise-math.c
@@ -4,10 +4,34 @@
 typedef short int si8 __attribute__((ext_vector_type(8)));
 typedef unsigned int u4 __attribute__((ext_vector_type(4)));
 
+void builtin_abs(float f1, float f2, double d1, double d2, float4 vf1, float4 vf2, si8 vi1, si8 vi2, long long int i1, long long int i2) {
+  // CHECK-LABEL: builtin_abs(
+  // CHECK:  [[F1:%.+]] = load float, float* %f1.addr, align 4
+  // CHECK-NEXT:  call float @llvm.fabs.f32(float [[F1]])
+  f2 = __builtin_elementwise_abs(f1);
+
+  // CHECK:  [[D1:%.+]] = load double, double* %d1.addr, align 8
+  // CHECK-NEXT: call double @llvm.fabs.f64(double [[D1]])
+  d2 = __builtin_elementwise_abs(d1);
+
+  // CHECK:  [[VF1:%.+]] = load <4 x float>, <4 x float>* %vf1.addr, align 16
+  // CHECK-NEXT: call <4 x float> @llvm.fabs.v4f32(<4 x float> [[VF1]])
+  vf2 = __builtin_elementwise_abs(vf1);
+
+  // CHECK:  [[I1:%.+]] = load i64, i64* %i1.addr, align 8
+  // CHECK-NEXT: call i64 @llvm.abs.i64(i64 [[I1]], i1 false)
+  i2 = __builtin_elementwise_abs(i1);
+
+  // CHECK:  [[VI1:%.+]] = load <8 x i16>, <8 x i16>* %vi1.addr, align 16
+  // CHECK-NEXT: call <8 x i16> @llvm.abs.v8i16(<8 x i16> [[VI1]], i1 false)
+  vi2 = __builtin_elementwise_abs(vi1);
+}
+
 void builtin_max(float f1, float f2, double d1, double d2, float4 vf1,
  float4 vf2, long long int i1, long long int i2, si8 vi1,
  si8 vi2, unsigned u1, unsigned u2, u4 vu1, u4 vu2) {
   // CHECK-LABEL: define void @builtin_max(
+
   // CHECK:  [[F1:%.+]] = load float, float* %f1.addr, align 4
   // CHECK-NEXT: [[F2:%.+]] = load float, float* %f2.addr, align 4
   // CHECK-NEXT:  call float @llvm.maxnum.f32(float %0, float %1)
Index: clang/lib/Sema/SemaChecking.cpp
===
--- clang/lib/Sema/SemaChecking.cpp
+++ clang/lib/Sema/SemaChecking.cpp
@@ -1976,9 +1976,12 @@
 break;
   }
 
+  case Builtin::BI__builtin_elementwise_abs:
+return SemaBuiltinElementwiseMathOneArg(TheCall, TheCallResult);
+
   case Builtin::BI__builtin_elementwise_min:
   case Builtin::BI__builtin_elementwise_max:
-return SemaBuiltinElementwiseMath(TheCall, TheCallResult);
+return SemaBuiltinElementwiseMathTwoArgs(TheCall, TheCallResult);
 
   case Builtin::BI__builtin_matrix_transpose:
 return SemaBuiltinMatrixTranspose(TheCall, TheCallResult);
@@ -16653,8 +16656,32 @@
  _2, _3, _4));
 }
 
-ExprResult Sema::SemaBuiltinElementwiseMath(

[PATCH] D111529: Specify Clang vector builtins.

2021-10-18 Thread Florian Hahn via Phabricator via cfe-commits
fhahn updated this revision to Diff 380351.
fhahn marked an inline comment as done.
fhahn added a comment.

Thanks for the latest set of comments!

I tried to incorporate the suggestions about improving the reduction wording. I 
also added an example.

I also put up 2 patches to start with the implementation of min/max and the abs 
builtins in D111985  and D111986 
. I adjusted the supported types for 
`__builtin_elementwise_abs` to *signed* integer and floating point types.


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D111529/new/

https://reviews.llvm.org/D111529

Files:
  clang/docs/LanguageExtensions.rst


Index: clang/docs/LanguageExtensions.rst
===
--- clang/docs/LanguageExtensions.rst
+++ clang/docs/LanguageExtensions.rst
@@ -506,6 +506,82 @@
   If it's an extension (OpenCL) vector, it's only available in C and OpenCL C.
   And it selects base on signedness of the condition operands (OpenCL v1.1 
s6.3.9).
 
+Vector Builtins
+---
+
+**Note: The implementation of vector builtins is work-in-progress and 
incomplete.**
+
+In addition to the operators mentioned above, Clang provides a set of builtins
+to perform additional operations on certain scalar and vector types.
+
+Let ``T`` be one of the following types:
+
+* an integer type (as in C2x 6.2.5p19), but excluding enumerated types and 
_Bool
+* the standard floating types float or double
+* a half-precision floating point type, if one is supported on the target
+* a vector type.
+
+For scalar types, consider the operation applied to a vector with a single 
element.
+
+*Elementwise Builtins*
+
+Each builtin returns a vector equivalent to applying the specified operation
+elementwise to the input.
+
+Unless specified otherwise operation(±0) = ±0 and operation(±infinity) = 
±infinity
+
+= 
 
=
+ Name  Operation   
 Supported element types
+= 
 
=
+ T __builtin_elementwise_abs(T x)  return the absolute value of a 
number x   signed integer and floating point types
+ T __builtin_elementwise_ceil(T x) return the smallest integral value 
greater than or equal to x floating point types
+ T __builtin_elementwise_floor(T x)return the largest integral value 
less than or equal to x floating point types
+ T __builtin_elementwise_roundeven(T x)round x to the nearest integer 
value in floating point format,floating point types
+   rounding halfway cases to even 
(that is, to the nearest value
+   that is an even integer), 
regardless of the current rounding
+   direction.
+ T__builtin_elementwise_trunc(T x) return the integral value nearest 
to but no larger in floating point types
+   magnitude than x
+ T __builtin_elementwise_max(T x, T y) return x or y, whichever is larger  
  integer and floating point types
+ T __builtin_elementwise_min(T x, T y) return x or y, whichever is smaller 
  integer and floating point types
+= 
 
=
+
+
+*Reduction Builtins*
+
+Each builtin returns a scalar equivalent to applying the specified
+operation(x, y) as recursive even-odd pairwise reduction to all vector
+elements. ``operation(x, y)`` is repeatedly applied to each non-overlapping
+even-odd element pair with indices ``i * 2`` and ``i * 2 + 1`` with
+``i in [0, Number of elements / 2)``. If the numbers of elements is not a
+multiple of 2, the vector is padded with a neutral element for the reduction
+operation at the end.
+
+Example:
+
+.. code-block:: c++
+
+__builtin_reduce_fadd([e3, e2, e1, e0]) = __builtin_reduced_fadd([e3 + e2, 
e1 + e0])
+= (e3 + e2) + (e1 + e0)
+
+
+Let ``VT`` be a vector type and ``ET`` the element type of ``VT``.
+
+=== 
 
==
+ NameOperation 
   Supported element types
+=== 
 
===

[PATCH] D111529: Specify Clang vector builtins.

2021-10-18 Thread Florian Hahn via Phabricator via cfe-commits
fhahn updated this revision to Diff 380352.
fhahn marked an inline comment as done.
fhahn added a comment.

adjust padding wording.


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D111529/new/

https://reviews.llvm.org/D111529

Files:
  clang/docs/LanguageExtensions.rst


Index: clang/docs/LanguageExtensions.rst
===
--- clang/docs/LanguageExtensions.rst
+++ clang/docs/LanguageExtensions.rst
@@ -506,6 +506,82 @@
   If it's an extension (OpenCL) vector, it's only available in C and OpenCL C.
   And it selects base on signedness of the condition operands (OpenCL v1.1 
s6.3.9).
 
+Vector Builtins
+---
+
+**Note: The implementation of vector builtins is work-in-progress and 
incomplete.**
+
+In addition to the operators mentioned above, Clang provides a set of builtins
+to perform additional operations on certain scalar and vector types.
+
+Let ``T`` be one of the following types:
+
+* an integer type (as in C2x 6.2.5p19), but excluding enumerated types and 
_Bool
+* the standard floating types float or double
+* a half-precision floating point type, if one is supported on the target
+* a vector type.
+
+For scalar types, consider the operation applied to a vector with a single 
element.
+
+*Elementwise Builtins*
+
+Each builtin returns a vector equivalent to applying the specified operation
+elementwise to the input.
+
+Unless specified otherwise operation(±0) = ±0 and operation(±infinity) = 
±infinity
+
+= 
 
=
+ Name  Operation   
 Supported element types
+= 
 
=
+ T __builtin_elementwise_abs(T x)  return the absolute value of a 
number x   signed integer and floating point types
+ T __builtin_elementwise_ceil(T x) return the smallest integral value 
greater than or equal to x floating point types
+ T __builtin_elementwise_floor(T x)return the largest integral value 
less than or equal to x floating point types
+ T __builtin_elementwise_roundeven(T x)round x to the nearest integer 
value in floating point format,floating point types
+   rounding halfway cases to even 
(that is, to the nearest value
+   that is an even integer), 
regardless of the current rounding
+   direction.
+ T__builtin_elementwise_trunc(T x) return the integral value nearest 
to but no larger in floating point types
+   magnitude than x
+ T __builtin_elementwise_max(T x, T y) return x or y, whichever is larger  
  integer and floating point types
+ T __builtin_elementwise_min(T x, T y) return x or y, whichever is smaller 
  integer and floating point types
+= 
 
=
+
+
+*Reduction Builtins*
+
+Each builtin returns a scalar equivalent to applying the specified
+operation(x, y) as recursive even-odd pairwise reduction to all vector
+elements. ``operation(x, y)`` is repeatedly applied to each non-overlapping
+even-odd element pair with indices ``i * 2`` and ``i * 2 + 1`` with
+``i in [0, Number of elements / 2)``. If the numbers of elements is not a
+power of 2, the vector is widening with neutral elements for the reduction
+at the end to the next power of 2.
+
+Example:
+
+.. code-block:: c++
+
+__builtin_reduce_fadd([e3, e2, e1, e0]) = __builtin_reduced_fadd([e3 + e2, 
e1 + e0])
+= (e3 + e2) + (e1 + e0)
+
+
+Let ``VT`` be a vector type and ``ET`` the element type of ``VT``.
+
+=== 
 
==
+ NameOperation 
   Supported element types
+=== 
 
==
+ ET __builtin_reduce_max(VT a)   return x or y, whichever is larger; 
If exactly one argument is   integer and floating point types
+ a NaN, return the other argument. If 
both arguments are NaNs,
+ fmax() return a NaN.
+ ET __builtin_reduce_min(VT a)   return x or y, whichever i

[PATCH] D111529: Specify Clang vector builtins.

2021-10-18 Thread Florian Hahn via Phabricator via cfe-commits
fhahn marked 2 inline comments as done.
fhahn added inline comments.



Comment at: clang/docs/LanguageExtensions.rst:553
+Each builtin returns a scalar equivalent to applying the specified
+operation(x, y) as horizontal recursive pairwise reduction to all vector
+elements. In each reduction step, ``operation(x, y)`` is applied to adjacent

kparzysz wrote:
> It's really not clear what "horizontal recursive pairwise" means unless one 
> has read the mailing list discussions.  Maybe you could spell it out, e.g. 
> "recursive even-odd pairwise reduction" or something like that.
Thanks, I used that wording!



Comment at: clang/docs/LanguageExtensions.rst:552
+operation(x, y) as pairwise tree reduction to the input. The pairs are formed
+by concatenating both inputs and pairing adjacent elements.
+

craig.topper wrote:
> fhahn wrote:
> > craig.topper wrote:
> > > scanon wrote:
> > > > fhahn wrote:
> > > > > craig.topper wrote:
> > > > > > I'm not sure I understand what is being concatenated here.
> > > > > I tried to spell it out more clearly. I'm still not sure if that 
> > > > > spells it out as clearly as possibly and I'd appreciate any 
> > > > > suggestions on how to improve the wording.
> > > > It's unclear because there's no apparent "first" or "second" vector; 
> > > > there's just a single argument, and the result isn't a vector, it's a 
> > > > scalar. I think you want to say something like: "the operation is 
> > > > repeatedly applied to adjacent pairs of elements until the result is a 
> > > > scalar" and then provide a worked example.
> > > The input is a single vector. I'm not understanding where we get a second 
> > > vector to concatenate.
> > Oh yes, now I see where the confusion was coming from. I was thinking about 
> > the reduction tree and how the input is broken up. Sorry for the confusing 
> > wording. I gave it another try, should be much simpler again now.
> Should it somehow mention the pair is the even element `i` and the odd 
> element `i+1`. There are n-1 adjacent pairs in an n element vector, but we 
> want non-overlapping pairs.
> 
> Should probably spell out the non-power2 behavior. Presumably we pad identity 
> elements after the last element to widen the vector out to a power 2 and then 
> proceed normally?
> Should it somehow mention the pair is the even element i and the odd element 
> i+1. There are n-1 adjacent pairs in an n element vector, but we want 
> non-overlapping pairs.

Thanks, I tried to update the wording to make it clear that it operates on 
even-odd non-overlapping pairs.


> Should probably spell out the non-power2 behavior. Presumably we pad identity 
> elements after the last element to widen the vector out to a power 2 and then 
> proceed normally?

Good point, done!

>  I think you want to say something like: "the operation is repeatedly applied 
> to adjacent pairs of elements until the result is a scalar" and then provide 
> a worked example.

Used and added an example.


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D111529/new/

https://reviews.llvm.org/D111529

___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D111985: [Clang] Add elementwise min/max builtins.

2021-10-18 Thread Florian Hahn via Phabricator via cfe-commits
fhahn updated this revision to Diff 380409.
fhahn added a comment.

polish tests a bit


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D111985/new/

https://reviews.llvm.org/D111985

Files:
  clang/include/clang/Basic/Builtins.def
  clang/include/clang/Basic/DiagnosticSemaKinds.td
  clang/include/clang/Sema/Sema.h
  clang/lib/CodeGen/CGBuiltin.cpp
  clang/lib/Sema/SemaChecking.cpp
  clang/test/CodeGen/builtins-elementwise-math.c
  clang/test/Sema/builtins-elementwise-math.c

Index: clang/test/Sema/builtins-elementwise-math.c
===
--- /dev/null
+++ clang/test/Sema/builtins-elementwise-math.c
@@ -0,0 +1,42 @@
+// RUN: %clang_cc1 %s -pedantic -verify -triple=x86_64-apple-darwin9
+
+typedef float float4 __attribute__((ext_vector_type(4)));
+typedef int int3 __attribute__((ext_vector_type(3)));
+
+struct Foo {
+  char *p;
+};
+
+void test_builtin_elementwise_max(int i, double d, float4 v, int3 iv) {
+  i = __builtin_elementwise_max(i, d);
+  // expected-error@-1 {{argument types do not match, 'int' != 'double'}}
+
+  struct Foo s = __builtin_elementwise_max(i, i);
+  // expected-error@-1 {{initializing 'struct Foo' with an expression of incompatible type 'int'}}
+
+  i = __builtin_elementwise_max(i);
+  // expected-error@-1 {{too few arguments to function call, expected 2, have 1}}
+
+  i = __builtin_elementwise_max();
+  // expected-error@-1 {{too few arguments to function call, expected 2, have 0}}
+
+  i = __builtin_elementwise_max(v, iv);
+  // expected-error@-1 {{argument types do not match, 'float4' (vector of 4 'float' values) != 'int3' (vector of 3 'int' values)}}
+}
+
+void test_builtin_elementwise_min(int i, double d, float4 v, int3 iv) {
+  i = __builtin_elementwise_min(i, d);
+  // expected-error@-1 {{argument types do not match, 'int' != 'double'}}
+
+  struct Foo s = __builtin_elementwise_min(i, i);
+  // expected-error@-1 {{initializing 'struct Foo' with an expression of incompatible type 'int'}}
+
+  i = __builtin_elementwise_min(i);
+  // expected-error@-1 {{too few arguments to function call, expected 2, have 1}}
+
+  i = __builtin_elementwise_min();
+  // expected-error@-1 {{too few arguments to function call, expected 2, have 0}}
+
+  i = __builtin_elementwise_min(v, iv);
+  // expected-error@-1 {{argument types do not match, 'float4' (vector of 4 'float' values) != 'int3' (vector of 3 'int' values)}}
+}
Index: clang/test/CodeGen/builtins-elementwise-math.c
===
--- /dev/null
+++ clang/test/CodeGen/builtins-elementwise-math.c
@@ -0,0 +1,88 @@
+// RUN: %clang_cc1 -disable-noundef-analysis -triple x86_64-apple-darwin %s -emit-llvm -disable-llvm-passes -o - | FileCheck %s
+
+typedef float float4 __attribute__((ext_vector_type(4)));
+typedef short int si8 __attribute__((ext_vector_type(8)));
+typedef unsigned int u4 __attribute__((ext_vector_type(4)));
+
+void test_builtin_elementwise_max(float f1, float f2, double d1, double d2,
+  float4 vf1, float4 vf2, long long int i1,
+  long long int i2, si8 vi1,si8 vi2,
+  unsigned u1, unsigned u2, u4 vu1, u4 vu2) {
+  // CHECK-LABEL: define void @test_builtin_elementwise_max(
+
+  // CHECK:  [[F1:%.+]] = load float, float* %f1.addr, align 4
+  // CHECK-NEXT: [[F2:%.+]] = load float, float* %f2.addr, align 4
+  // CHECK-NEXT:  call float @llvm.maxnum.f32(float %0, float %1)
+  f1 = __builtin_elementwise_max(f1, f2);
+
+  // CHECK:  [[D1:%.+]] = load double, double* %d1.addr, align 8
+  // CHECK-NEXT: [[D2:%.+]] = load double, double* %d2.addr, align 8
+  // CHECK-NEXT: call double @llvm.maxnum.f64(double [[D1]], double [[D2]])
+  d1 = __builtin_elementwise_max(d1, d2);
+
+  // CHECK:  [[VF1:%.+]] = load <4 x float>, <4 x float>* %vf1.addr, align 16
+  // CHECK-NEXT: [[VF2:%.+]] = load <4 x float>, <4 x float>* %vf2.addr, align 16
+  // CHECK-NEXT: call <4 x float> @llvm.maxnum.v4f32(<4 x float> [[VF1]], <4 x float> [[VF2]])
+  vf1 = __builtin_elementwise_max(vf1, vf2);
+
+  // CHECK:  [[I1:%.+]] = load i64, i64* %i1.addr, align 8
+  // CHECK-NEXT: [[I2:%.+]] = load i64, i64* %i2.addr, align 8
+  // CHECK-NEXT: call i64 @llvm.smax.i64(i64 [[I1]], i64 [[I2]])
+  i1 = __builtin_elementwise_max(i1, i2);
+
+  // CHECK:  [[VI1:%.+]] = load <8 x i16>, <8 x i16>* %vi1.addr, align 16
+  // CHECK-NEXT: [[VI2:%.+]] = load <8 x i16>, <8 x i16>* %vi2.addr, align 16
+  // CHECK-NEXT: call <8 x i16> @llvm.smax.v8i16(<8 x i16> [[VI1]], <8 x i16> [[VI2]])
+  vi1 = __builtin_elementwise_max(vi1, vi2);
+
+  // CHECK:  [[U1:%.+]] = load i32, i32* %u1.addr, align 4
+  // CHECK-NEXT: [[U2:%.+]] = load i32, i32* %u2.addr, align 4
+  // CHECK-NEXT: call i32 @llvm.umax.i32(i32 [[U1]], i32 [[U2]])
+  u1 = __builtin_elementwise_max(u1, u2);
+
+  // CHECK:  [[VU1:%.+]] = load <4 x i32>, <4 x

[PATCH] D111986: [Clang] Add elementwise abs builtin.

2021-10-18 Thread Florian Hahn via Phabricator via cfe-commits
fhahn updated this revision to Diff 380411.
fhahn added a comment.

polish tests a bit


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D111986/new/

https://reviews.llvm.org/D111986

Files:
  clang/include/clang/Basic/Builtins.def
  clang/include/clang/Basic/DiagnosticSemaKinds.td
  clang/include/clang/Sema/Sema.h
  clang/lib/CodeGen/CGBuiltin.cpp
  clang/lib/Sema/SemaChecking.cpp
  clang/test/CodeGen/builtins-elementwise-math.c
  clang/test/Sema/builtins-elementwise-math.c

Index: clang/test/Sema/builtins-elementwise-math.c
===
--- clang/test/Sema/builtins-elementwise-math.c
+++ clang/test/Sema/builtins-elementwise-math.c
@@ -2,11 +2,32 @@
 
 typedef float float4 __attribute__((ext_vector_type(4)));
 typedef int int3 __attribute__((ext_vector_type(3)));
+typedef unsigned unsigned4 __attribute__((ext_vector_type(4)));
 
 struct Foo {
   char *p;
 };
 
+void test_builtin_elementwise_abs(int i, double d, float4 v, int3 iv, unsigned u, unsigned4 uv) {
+  struct Foo s = __builtin_elementwise_abs(i);
+  // expected-error@-1 {{initializing 'struct Foo' with an expression of incompatible type 'int'}}
+
+  i = __builtin_elementwise_abs();
+  // expected-error@-1 {{too few arguments to function call, expected 1, have 0}}
+
+  i = __builtin_elementwise_abs(i, i);
+  // expected-error@-1 {{too many arguments to function call, expected 1, have 2}}
+
+  i = __builtin_elementwise_abs(v);
+  // expected-error@-1 {{assigning to 'int' from incompatible type 'float4' (vector of 4 'float' values)}}
+
+  u = __builtin_elementwise_abs(u);
+  // expected-error@-1 {{argument must have a signed integer or floating point type, but was an unsigned integer type}}
+
+  uv = __builtin_elementwise_abs(uv);
+  // expected-error@-1 {{argument must have a signed integer or floating point type, but was an unsigned integer type}}
+}
+
 void test_builtin_elementwise_max(int i, double d, float4 v, int3 iv) {
   i = __builtin_elementwise_max(i, d);
   // expected-error@-1 {{argument types do not match, 'int' != 'double'}}
Index: clang/test/CodeGen/builtins-elementwise-math.c
===
--- clang/test/CodeGen/builtins-elementwise-math.c
+++ clang/test/CodeGen/builtins-elementwise-math.c
@@ -4,12 +4,36 @@
 typedef short int si8 __attribute__((ext_vector_type(8)));
 typedef unsigned int u4 __attribute__((ext_vector_type(4)));
 
+void test_builtin_elementwise_abs(float f1, float f2, double d1, double d2,
+  float4 vf1, float4 vf2, si8 vi1, si8 vi2,
+  long long int i1, long long int i2) {
+  // CHECK-LABEL: define void @test_builtin_elementwise_abs(
+  // CHECK:  [[F1:%.+]] = load float, float* %f1.addr, align 4
+  // CHECK-NEXT:  call float @llvm.fabs.f32(float [[F1]])
+  f2 = __builtin_elementwise_abs(f1);
+
+  // CHECK:  [[D1:%.+]] = load double, double* %d1.addr, align 8
+  // CHECK-NEXT: call double @llvm.fabs.f64(double [[D1]])
+  d2 = __builtin_elementwise_abs(d1);
+
+  // CHECK:  [[VF1:%.+]] = load <4 x float>, <4 x float>* %vf1.addr, align 16
+  // CHECK-NEXT: call <4 x float> @llvm.fabs.v4f32(<4 x float> [[VF1]])
+  vf2 = __builtin_elementwise_abs(vf1);
+
+  // CHECK:  [[I1:%.+]] = load i64, i64* %i1.addr, align 8
+  // CHECK-NEXT: call i64 @llvm.abs.i64(i64 [[I1]], i1 false)
+  i2 = __builtin_elementwise_abs(i1);
+
+  // CHECK:  [[VI1:%.+]] = load <8 x i16>, <8 x i16>* %vi1.addr, align 16
+  // CHECK-NEXT: call <8 x i16> @llvm.abs.v8i16(<8 x i16> [[VI1]], i1 false)
+  vi2 = __builtin_elementwise_abs(vi1);
+}
+
 void test_builtin_elementwise_max(float f1, float f2, double d1, double d2,
   float4 vf1, float4 vf2, long long int i1,
   long long int i2, si8 vi1,si8 vi2,
   unsigned u1, unsigned u2, u4 vu1, u4 vu2) {
   // CHECK-LABEL: define void @test_builtin_elementwise_max(
-
   // CHECK:  [[F1:%.+]] = load float, float* %f1.addr, align 4
   // CHECK-NEXT: [[F2:%.+]] = load float, float* %f2.addr, align 4
   // CHECK-NEXT:  call float @llvm.maxnum.f32(float %0, float %1)
Index: clang/lib/Sema/SemaChecking.cpp
===
--- clang/lib/Sema/SemaChecking.cpp
+++ clang/lib/Sema/SemaChecking.cpp
@@ -1976,9 +1976,12 @@
 break;
   }
 
+  case Builtin::BI__builtin_elementwise_abs:
+return SemaBuiltinElementwiseMathOneArg(TheCall, TheCallResult);
+
   case Builtin::BI__builtin_elementwise_min:
   case Builtin::BI__builtin_elementwise_max:
-return SemaBuiltinElementwiseMath(TheCall, TheCallResult);
+return SemaBuiltinElementwiseMathTwoArgs(TheCall, TheCallResult);
 
   case Builtin::BI__builtin_matrix_transpose:
 return SemaBuiltinMatrixTranspose(TheCall, TheCallResult);
@@ -16653,8 +16656,32 @@
  _2, _3, _

[PATCH] D112001: [Clang] Add min/max reduction builtins.

2021-10-18 Thread Florian Hahn via Phabricator via cfe-commits
fhahn created this revision.
fhahn added reviewers: aaron.ballman, scanon, craig.topper, rjmccall, 
erichkeane.
fhahn requested review of this revision.
Herald added a project: clang.

This patch implements __builtin_reduce_max and __builtin_reduce_min as
specified in D111529 .

The order of operations does not matter for min or max reductions and
they can be directly lowered to the corresponding
llvm.vector.reduce.{fmin,fmax,umin,umax,smin,smax} intrinsic calls.


Repository:
  rG LLVM Github Monorepo

https://reviews.llvm.org/D112001

Files:
  clang/include/clang/Basic/Builtins.def
  clang/include/clang/Sema/Sema.h
  clang/lib/CodeGen/CGBuiltin.cpp
  clang/lib/Sema/SemaChecking.cpp
  clang/test/CodeGen/builtins-elementwise-math.c
  clang/test/Sema/builtins-elementwise-math.c

Index: clang/test/Sema/builtins-elementwise-math.c
===
--- clang/test/Sema/builtins-elementwise-math.c
+++ clang/test/Sema/builtins-elementwise-math.c
@@ -61,3 +61,31 @@
   i = __builtin_elementwise_min(v, iv);
   // expected-error@-1 {{argument types do not match, 'float4' (vector of 4 'float' values) != 'int3' (vector of 3 'int' values)}}
 }
+
+void test_builtin_reduce_max(int i, float4 v, int3 iv) {
+  struct Foo s = __builtin_reduce_max(iv);
+  // expected-error@-1 {{initializing 'struct Foo' with an expression of incompatible type 'int'}}
+
+  i = __builtin_reduce_max(v, v);
+  // expected-error@-1 {{too many arguments to function call, expected 1, have 2}}
+
+  i = __builtin_reduce_max();
+  // expected-error@-1 {{too few arguments to function call, expected 1, have 0}}
+
+  i = __builtin_reduce_max(i);
+  // expected-error@-1 {{argument must have a vector type, but was 'int'}}
+}
+
+void test_builtin_reduce_min(int i, float4 v, int3 iv) {
+  struct Foo s = __builtin_reduce_min(iv);
+  // expected-error@-1 {{initializing 'struct Foo' with an expression of incompatible type 'int'}}
+
+  i = __builtin_reduce_min(v, v);
+  // expected-error@-1 {{too many arguments to function call, expected 1, have 2}}
+
+  i = __builtin_reduce_min();
+  // expected-error@-1 {{too few arguments to function call, expected 1, have 0}}
+
+  i = __builtin_reduce_min(i);
+  // expected-error@-1 {{argument must have a vector type, but was 'int'}}
+}
Index: clang/test/CodeGen/builtins-elementwise-math.c
===
--- clang/test/CodeGen/builtins-elementwise-math.c
+++ clang/test/CodeGen/builtins-elementwise-math.c
@@ -110,3 +110,33 @@
   // CHECK-NEXT: call <4 x i32> @llvm.umin.v4i32(<4 x i32> [[VU1]], <4 x i32> [[VU2]])
   vu1 = __builtin_elementwise_min(vu1, vu2);
 }
+
+void test_builtin_reduce_max(float4 vf1, si8 vi1, u4 vu1) {
+  // CHECK-LABEL: define void @test_builtin_reduce_max(
+  // CHECK:  [[VF1:%.+]] = load <4 x float>, <4 x float>* %vf1.addr, align 16
+  // CHECK-NEXT: call float @llvm.vector.reduce.fmax.v4f32(<4 x float> [[VF1]])
+  float r1 = __builtin_reduce_max(vf1);
+
+  // CHECK:  [[VI1:%.+]] = load <8 x i16>, <8 x i16>* %vi1.addr, align 16
+  // CHECK-NEXT: call i16 @llvm.vector.reduce.smax.v8i16(<8 x i16> [[VI1]])
+  short r2 = __builtin_reduce_max(vi1);
+
+  // CHECK:  [[VU1:%.+]] = load <4 x i32>, <4 x i32>* %vu1.addr, align 16
+  // CHECK-NEXT: call i32 @llvm.vector.reduce.umax.v4i32(<4 x i32> [[VU1]])
+  unsigned r3 = __builtin_reduce_max(vu1);
+}
+
+void test_builtin_reduce_min(float4 vf1, si8 vi1, u4 vu1) {
+  // CHECK-LABEL: define void @test_builtin_reduce_min(
+  // CHECK:  [[VF1:%.+]] = load <4 x float>, <4 x float>* %vf1.addr, align 16
+  // CHECK-NEXT: call float @llvm.vector.reduce.fmin.v4f32(<4 x float> [[VF1]])
+  float r1 = __builtin_reduce_min(vf1);
+
+  // CHECK:  [[VI1:%.+]] = load <8 x i16>, <8 x i16>* %vi1.addr, align 16
+  // CHECK-NEXT: call i16 @llvm.vector.reduce.smin.v8i16(<8 x i16> [[VI1]])
+  short r2 = __builtin_reduce_min(vi1);
+
+  // CHECK:  [[VU1:%.+]] = load <4 x i32>, <4 x i32>* %vu1.addr, align 16
+  // CHECK-NEXT: call i32 @llvm.vector.reduce.umin.v4i32(<4 x i32> [[VU1]])
+  unsigned r3 = __builtin_reduce_min(vu1);
+}
Index: clang/lib/Sema/SemaChecking.cpp
===
--- clang/lib/Sema/SemaChecking.cpp
+++ clang/lib/Sema/SemaChecking.cpp
@@ -1978,11 +1978,15 @@
 
   case Builtin::BI__builtin_elementwise_abs:
 return SemaBuiltinElementwiseMathOneArg(TheCall, TheCallResult);
-
   case Builtin::BI__builtin_elementwise_min:
   case Builtin::BI__builtin_elementwise_max:
 return SemaBuiltinElementwiseMathTwoArgs(TheCall, TheCallResult);
 
+  case Builtin::BI__builtin_reduce_max:
+  case Builtin::BI__builtin_reduce_min:
+return SemaBuiltinReduceMath(TheCall, TheCallResult);
+
+
   case Builtin::BI__builtin_matrix_transpose:
 return SemaBuiltinMatrixTranspose(TheCall, TheCallResult);
   case Builtin::BI__builtin_matrix_column_major_load:
@@ -16656,6 +16660,

[PATCH] D112001: [Clang] Add min/max reduction builtins.

2021-10-18 Thread Florian Hahn via Phabricator via cfe-commits
fhahn updated this revision to Diff 380486.
fhahn added a comment.

Remove stray `!TyA->getAs()` check.


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D112001/new/

https://reviews.llvm.org/D112001

Files:
  clang/include/clang/Basic/Builtins.def
  clang/include/clang/Sema/Sema.h
  clang/lib/CodeGen/CGBuiltin.cpp
  clang/lib/Sema/SemaChecking.cpp
  clang/test/CodeGen/builtins-elementwise-math.c
  clang/test/Sema/builtins-elementwise-math.c

Index: clang/test/Sema/builtins-elementwise-math.c
===
--- clang/test/Sema/builtins-elementwise-math.c
+++ clang/test/Sema/builtins-elementwise-math.c
@@ -61,3 +61,31 @@
   i = __builtin_elementwise_min(v, iv);
   // expected-error@-1 {{argument types do not match, 'float4' (vector of 4 'float' values) != 'int3' (vector of 3 'int' values)}}
 }
+
+void test_builtin_reduce_max(int i, float4 v, int3 iv) {
+  struct Foo s = __builtin_reduce_max(iv);
+  // expected-error@-1 {{initializing 'struct Foo' with an expression of incompatible type 'int'}}
+
+  i = __builtin_reduce_max(v, v);
+  // expected-error@-1 {{too many arguments to function call, expected 1, have 2}}
+
+  i = __builtin_reduce_max();
+  // expected-error@-1 {{too few arguments to function call, expected 1, have 0}}
+
+  i = __builtin_reduce_max(i);
+  // expected-error@-1 {{argument must have a vector type, but was 'int'}}
+}
+
+void test_builtin_reduce_min(int i, float4 v, int3 iv) {
+  struct Foo s = __builtin_reduce_min(iv);
+  // expected-error@-1 {{initializing 'struct Foo' with an expression of incompatible type 'int'}}
+
+  i = __builtin_reduce_min(v, v);
+  // expected-error@-1 {{too many arguments to function call, expected 1, have 2}}
+
+  i = __builtin_reduce_min();
+  // expected-error@-1 {{too few arguments to function call, expected 1, have 0}}
+
+  i = __builtin_reduce_min(i);
+  // expected-error@-1 {{argument must have a vector type, but was 'int'}}
+}
Index: clang/test/CodeGen/builtins-elementwise-math.c
===
--- clang/test/CodeGen/builtins-elementwise-math.c
+++ clang/test/CodeGen/builtins-elementwise-math.c
@@ -110,3 +110,33 @@
   // CHECK-NEXT: call <4 x i32> @llvm.umin.v4i32(<4 x i32> [[VU1]], <4 x i32> [[VU2]])
   vu1 = __builtin_elementwise_min(vu1, vu2);
 }
+
+void test_builtin_reduce_max(float4 vf1, si8 vi1, u4 vu1) {
+  // CHECK-LABEL: define void @test_builtin_reduce_max(
+  // CHECK:  [[VF1:%.+]] = load <4 x float>, <4 x float>* %vf1.addr, align 16
+  // CHECK-NEXT: call float @llvm.vector.reduce.fmax.v4f32(<4 x float> [[VF1]])
+  float r1 = __builtin_reduce_max(vf1);
+
+  // CHECK:  [[VI1:%.+]] = load <8 x i16>, <8 x i16>* %vi1.addr, align 16
+  // CHECK-NEXT: call i16 @llvm.vector.reduce.smax.v8i16(<8 x i16> [[VI1]])
+  short r2 = __builtin_reduce_max(vi1);
+
+  // CHECK:  [[VU1:%.+]] = load <4 x i32>, <4 x i32>* %vu1.addr, align 16
+  // CHECK-NEXT: call i32 @llvm.vector.reduce.umax.v4i32(<4 x i32> [[VU1]])
+  unsigned r3 = __builtin_reduce_max(vu1);
+}
+
+void test_builtin_reduce_min(float4 vf1, si8 vi1, u4 vu1) {
+  // CHECK-LABEL: define void @test_builtin_reduce_min(
+  // CHECK:  [[VF1:%.+]] = load <4 x float>, <4 x float>* %vf1.addr, align 16
+  // CHECK-NEXT: call float @llvm.vector.reduce.fmin.v4f32(<4 x float> [[VF1]])
+  float r1 = __builtin_reduce_min(vf1);
+
+  // CHECK:  [[VI1:%.+]] = load <8 x i16>, <8 x i16>* %vi1.addr, align 16
+  // CHECK-NEXT: call i16 @llvm.vector.reduce.smin.v8i16(<8 x i16> [[VI1]])
+  short r2 = __builtin_reduce_min(vi1);
+
+  // CHECK:  [[VU1:%.+]] = load <4 x i32>, <4 x i32>* %vu1.addr, align 16
+  // CHECK-NEXT: call i32 @llvm.vector.reduce.umin.v4i32(<4 x i32> [[VU1]])
+  unsigned r3 = __builtin_reduce_min(vu1);
+}
Index: clang/lib/Sema/SemaChecking.cpp
===
--- clang/lib/Sema/SemaChecking.cpp
+++ clang/lib/Sema/SemaChecking.cpp
@@ -1978,11 +1978,14 @@
 
   case Builtin::BI__builtin_elementwise_abs:
 return SemaBuiltinElementwiseMathOneArg(TheCall, TheCallResult);
-
   case Builtin::BI__builtin_elementwise_min:
   case Builtin::BI__builtin_elementwise_max:
 return SemaBuiltinElementwiseMathTwoArgs(TheCall, TheCallResult);
 
+  case Builtin::BI__builtin_reduce_max:
+  case Builtin::BI__builtin_reduce_min:
+return SemaBuiltinReduceMath(TheCall, TheCallResult);
+
   case Builtin::BI__builtin_matrix_transpose:
 return SemaBuiltinMatrixTranspose(TheCall, TheCallResult);
   case Builtin::BI__builtin_matrix_column_major_load:
@@ -16656,6 +16659,23 @@
  _2, _3, _4));
 }
 
+ExprResult Sema::SemaBuiltinReduceMath(CallExpr *TheCall,
+   ExprResult CallResult) {
+  if (checkArgCount(*this, TheCall, 1))
+return ExprError();
+
+  Expr *A = TheCall->getArg(0);
+  QualType TyA = A->getType();
+
+  const VectorType *VecTy 

[PATCH] D112001: [Clang] Add min/max reduction builtins.

2021-10-18 Thread Florian Hahn via Phabricator via cfe-commits
fhahn marked an inline comment as done.
fhahn added inline comments.



Comment at: clang/lib/Sema/SemaChecking.cpp:16673
+  if (!VecTy)
+  if (!TyA->getAs())
+  return Diag(A->getBeginLoc(), 
diag::err_elementwise_math_invalid_arg_type_2)

craig.topper wrote:
> Is this indented incorrectly? There appear to be 2 ifs at the same level
Yes they were, thanks! The `if (!TyA->getAs())` was a left-over 
from an earlier iteration. Removed.


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D112001/new/

https://reviews.llvm.org/D112001

___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D111529: Specify Clang vector builtins.

2021-10-18 Thread Florian Hahn via Phabricator via cfe-commits
fhahn updated this revision to Diff 380500.
fhahn marked an inline comment as done.
fhahn added a comment.

Fix wording: widening -> widened, thanks!


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D111529/new/

https://reviews.llvm.org/D111529

Files:
  clang/docs/LanguageExtensions.rst


Index: clang/docs/LanguageExtensions.rst
===
--- clang/docs/LanguageExtensions.rst
+++ clang/docs/LanguageExtensions.rst
@@ -506,6 +506,82 @@
   If it's an extension (OpenCL) vector, it's only available in C and OpenCL C.
   And it selects base on signedness of the condition operands (OpenCL v1.1 
s6.3.9).
 
+Vector Builtins
+---
+
+**Note: The implementation of vector builtins is work-in-progress and 
incomplete.**
+
+In addition to the operators mentioned above, Clang provides a set of builtins
+to perform additional operations on certain scalar and vector types.
+
+Let ``T`` be one of the following types:
+
+* an integer type (as in C2x 6.2.5p19), but excluding enumerated types and 
_Bool
+* the standard floating types float or double
+* a half-precision floating point type, if one is supported on the target
+* a vector type.
+
+For scalar types, consider the operation applied to a vector with a single 
element.
+
+*Elementwise Builtins*
+
+Each builtin returns a vector equivalent to applying the specified operation
+elementwise to the input.
+
+Unless specified otherwise operation(±0) = ±0 and operation(±infinity) = 
±infinity
+
+= 
 
=
+ Name  Operation   
 Supported element types
+= 
 
=
+ T __builtin_elementwise_abs(T x)  return the absolute value of a 
number x   signed integer and floating point types
+ T __builtin_elementwise_ceil(T x) return the smallest integral value 
greater than or equal to x floating point types
+ T __builtin_elementwise_floor(T x)return the largest integral value 
less than or equal to x floating point types
+ T __builtin_elementwise_roundeven(T x)round x to the nearest integer 
value in floating point format,floating point types
+   rounding halfway cases to even 
(that is, to the nearest value
+   that is an even integer), 
regardless of the current rounding
+   direction.
+ T__builtin_elementwise_trunc(T x) return the integral value nearest 
to but no larger in floating point types
+   magnitude than x
+ T __builtin_elementwise_max(T x, T y) return x or y, whichever is larger  
  integer and floating point types
+ T __builtin_elementwise_min(T x, T y) return x or y, whichever is smaller 
  integer and floating point types
+= 
 
=
+
+
+*Reduction Builtins*
+
+Each builtin returns a scalar equivalent to applying the specified
+operation(x, y) as recursive even-odd pairwise reduction to all vector
+elements. ``operation(x, y)`` is repeatedly applied to each non-overlapping
+even-odd element pair with indices ``i * 2`` and ``i * 2 + 1`` with
+``i in [0, Number of elements / 2)``. If the numbers of elements is not a
+power of 2, the vector is widened with neutral elements for the reduction
+at the end to the next power of 2.
+
+Example:
+
+.. code-block:: c++
+
+__builtin_reduce_fadd([e3, e2, e1, e0]) = __builtin_reduced_fadd([e3 + e2, 
e1 + e0])
+= (e3 + e2) + (e1 + e0)
+
+
+Let ``VT`` be a vector type and ``ET`` the element type of ``VT``.
+
+=== 
 
==
+ NameOperation 
   Supported element types
+=== 
 
==
+ ET __builtin_reduce_max(VT a)   return x or y, whichever is larger; 
If exactly one argument is   integer and floating point types
+ a NaN, return the other argument. If 
both arguments are NaNs,
+ fmax() return a NaN.
+ ET __builtin_reduce_min(VT a)   return x 

[PATCH] D111529: Specify Clang vector builtins.

2021-10-18 Thread Florian Hahn via Phabricator via cfe-commits
fhahn marked an inline comment as done.
fhahn added inline comments.



Comment at: clang/docs/LanguageExtensions.rst:557
+``i in [0, Number of elements / 2)``. If the numbers of elements is not a
+power of 2, the vector is widening with neutral elements for the reduction
+at the end to the next power of 2.

craig.topper wrote:
> widening -> widened
thanks, should be fixed!


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D111529/new/

https://reviews.llvm.org/D111529

___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D111529: Specify Clang vector builtins.

2021-10-19 Thread Florian Hahn via Phabricator via cfe-commits
fhahn updated this revision to Diff 380598.
fhahn marked an inline comment as done.
fhahn added a comment.

Thanks @kito-cheng, the example should use `__builtin_reduce_add` instead of 
`_fadd`! Fixed


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D111529/new/

https://reviews.llvm.org/D111529

Files:
  clang/docs/LanguageExtensions.rst


Index: clang/docs/LanguageExtensions.rst
===
--- clang/docs/LanguageExtensions.rst
+++ clang/docs/LanguageExtensions.rst
@@ -506,6 +506,82 @@
   If it's an extension (OpenCL) vector, it's only available in C and OpenCL C.
   And it selects base on signedness of the condition operands (OpenCL v1.1 
s6.3.9).
 
+Vector Builtins
+---
+
+**Note: The implementation of vector builtins is work-in-progress and 
incomplete.**
+
+In addition to the operators mentioned above, Clang provides a set of builtins
+to perform additional operations on certain scalar and vector types.
+
+Let ``T`` be one of the following types:
+
+* an integer type (as in C2x 6.2.5p19), but excluding enumerated types and 
_Bool
+* the standard floating types float or double
+* a half-precision floating point type, if one is supported on the target
+* a vector type.
+
+For scalar types, consider the operation applied to a vector with a single 
element.
+
+*Elementwise Builtins*
+
+Each builtin returns a vector equivalent to applying the specified operation
+elementwise to the input.
+
+Unless specified otherwise operation(±0) = ±0 and operation(±infinity) = 
±infinity
+
+= 
 
=
+ Name  Operation   
 Supported element types
+= 
 
=
+ T __builtin_elementwise_abs(T x)  return the absolute value of a 
number x   signed integer and floating point types
+ T __builtin_elementwise_ceil(T x) return the smallest integral value 
greater than or equal to x floating point types
+ T __builtin_elementwise_floor(T x)return the largest integral value 
less than or equal to x floating point types
+ T __builtin_elementwise_roundeven(T x)round x to the nearest integer 
value in floating point format,floating point types
+   rounding halfway cases to even 
(that is, to the nearest value
+   that is an even integer), 
regardless of the current rounding
+   direction.
+ T__builtin_elementwise_trunc(T x) return the integral value nearest 
to but no larger in floating point types
+   magnitude than x
+ T __builtin_elementwise_max(T x, T y) return x or y, whichever is larger  
  integer and floating point types
+ T __builtin_elementwise_min(T x, T y) return x or y, whichever is smaller 
  integer and floating point types
+= 
 
=
+
+
+*Reduction Builtins*
+
+Each builtin returns a scalar equivalent to applying the specified
+operation(x, y) as recursive even-odd pairwise reduction to all vector
+elements. ``operation(x, y)`` is repeatedly applied to each non-overlapping
+even-odd element pair with indices ``i * 2`` and ``i * 2 + 1`` with
+``i in [0, Number of elements / 2)``. If the numbers of elements is not a
+power of 2, the vector is widened with neutral elements for the reduction
+at the end to the next power of 2.
+
+Example:
+
+.. code-block:: c++
+
+__builtin_reduce_add([e3, e2, e1, e0]) = __builtin_reduced_add([e3 + e2, 
e1 + e0])
+   = (e3 + e2) + (e1 + e0)
+
+
+Let ``VT`` be a vector type and ``ET`` the element type of ``VT``.
+
+=== 
 
==
+ NameOperation 
   Supported element types
+=== 
 
==
+ ET __builtin_reduce_max(VT a)   return x or y, whichever is larger; 
If exactly one argument is   integer and floating point types
+ a NaN, return the other argument. If 
both arguments are NaNs,
+ fmax() return a NaN.
+ E

[PATCH] D111529: Specify Clang vector builtins.

2021-10-19 Thread Florian Hahn via Phabricator via cfe-commits
fhahn marked an inline comment as done.
fhahn added inline comments.



Comment at: clang/docs/LanguageExtensions.rst:579
+ NaNs, fmax() return a NaN.
+ ET __builtin_reduce_add(VT a)   \+
   integer and floating point types
+ ET __builtin_reduce_and(VT a)   & 
   integer types

kito-cheng wrote:
> The example above use `__builtin_reduce_fadd`, but not listed here? or should 
> we just use `__builtin_reduce_add` for floating point and fix the example?
Thanks it should be `_add` instead of `_fadd`. fixed.


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D111529/new/

https://reviews.llvm.org/D111529

___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D111529: Specify Clang vector builtins.

2021-10-19 Thread Florian Hahn via Phabricator via cfe-commits
fhahn updated this revision to Diff 380612.
fhahn marked an inline comment as done.
fhahn added a comment.

Following feedback from D111986 , explicitly 
spell out abs behavior of most negative integer as undefined.


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D111529/new/

https://reviews.llvm.org/D111529

Files:
  clang/docs/LanguageExtensions.rst


Index: clang/docs/LanguageExtensions.rst
===
--- clang/docs/LanguageExtensions.rst
+++ clang/docs/LanguageExtensions.rst
@@ -506,6 +506,83 @@
   If it's an extension (OpenCL) vector, it's only available in C and OpenCL C.
   And it selects base on signedness of the condition operands (OpenCL v1.1 
s6.3.9).
 
+Vector Builtins
+---
+
+**Note: The implementation of vector builtins is work-in-progress and 
incomplete.**
+
+In addition to the operators mentioned above, Clang provides a set of builtins
+to perform additional operations on certain scalar and vector types.
+
+Let ``T`` be one of the following types:
+
+* an integer type (as in C2x 6.2.5p19), but excluding enumerated types and 
_Bool
+* the standard floating types float or double
+* a half-precision floating point type, if one is supported on the target
+* a vector type.
+
+For scalar types, consider the operation applied to a vector with a single 
element.
+
+*Elementwise Builtins*
+
+Each builtin returns a vector equivalent to applying the specified operation
+elementwise to the input.
+
+Unless specified otherwise operation(±0) = ±0 and operation(±infinity) = 
±infinity
+
+= 
 
=
+ Name  Operation   
 Supported element types
+= 
 
=
+ T __builtin_elementwise_abs(T x)  return the absolute value of a 
number x; trying to take the  signed integer and floating point types
+   absolute value of the most negative 
integer is not defined
+ T __builtin_elementwise_ceil(T x) return the smallest integral value 
greater than or equal to xfloating point types
+ T __builtin_elementwise_floor(T x)return the largest integral value 
less than or equal to xfloating point types
+ T __builtin_elementwise_roundeven(T x)round x to the nearest integer 
value in floating point format,   floating point types
+   rounding halfway cases to even 
(that is, to the nearest value
+   that is an even integer), 
regardless of the current rounding
+   direction.
+ T__builtin_elementwise_trunc(T x) return the integral value nearest 
to but no larger infloating point types
+   magnitude than x
+ T __builtin_elementwise_max(T x, T y) return x or y, whichever is larger  
 integer and floating point types
+ T __builtin_elementwise_min(T x, T y) return x or y, whichever is smaller 
 integer and floating point types
+= 
 
=
+
+
+*Reduction Builtins*
+
+Each builtin returns a scalar equivalent to applying the specified
+operation(x, y) as recursive even-odd pairwise reduction to all vector
+elements. ``operation(x, y)`` is repeatedly applied to each non-overlapping
+even-odd element pair with indices ``i * 2`` and ``i * 2 + 1`` with
+``i in [0, Number of elements / 2)``. If the numbers of elements is not a
+power of 2, the vector is widened with neutral elements for the reduction
+at the end to the next power of 2.
+
+Example:
+
+.. code-block:: c++
+
+__builtin_reduce_add([e3, e2, e1, e0]) = __builtin_reduced_add([e3 + e2, 
e1 + e0])
+   = (e3 + e2) + (e1 + e0)
+
+
+Let ``VT`` be a vector type and ``ET`` the element type of ``VT``.
+
+=== 
 
==
+ NameOperation 
   Supported element types
+=== 
 
==
+ ET __builtin_reduce_max(VT a)   return x or y, whichever is larger; 
If exactly one argument is   integer and floating point types
+

[PATCH] D111986: [Clang] Add elementwise abs builtin.

2021-10-19 Thread Florian Hahn via Phabricator via cfe-commits
fhahn updated this revision to Diff 380618.
fhahn added a comment.

Pass is_int_min_poison=true to llvm.abs.* to reflect latest update to the 
specification to make taking abs of the most negative integer undefined.


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D111986/new/

https://reviews.llvm.org/D111986

Files:
  clang/include/clang/Basic/Builtins.def
  clang/include/clang/Basic/DiagnosticSemaKinds.td
  clang/include/clang/Sema/Sema.h
  clang/lib/CodeGen/CGBuiltin.cpp
  clang/lib/Sema/SemaChecking.cpp
  clang/test/CodeGen/builtins-elementwise-math.c
  clang/test/Sema/builtins-elementwise-math.c

Index: clang/test/Sema/builtins-elementwise-math.c
===
--- clang/test/Sema/builtins-elementwise-math.c
+++ clang/test/Sema/builtins-elementwise-math.c
@@ -2,11 +2,32 @@
 
 typedef float float4 __attribute__((ext_vector_type(4)));
 typedef int int3 __attribute__((ext_vector_type(3)));
+typedef unsigned unsigned4 __attribute__((ext_vector_type(4)));
 
 struct Foo {
   char *p;
 };
 
+void test_builtin_elementwise_abs(int i, double d, float4 v, int3 iv, unsigned u, unsigned4 uv) {
+  struct Foo s = __builtin_elementwise_abs(i);
+  // expected-error@-1 {{initializing 'struct Foo' with an expression of incompatible type 'int'}}
+
+  i = __builtin_elementwise_abs();
+  // expected-error@-1 {{too few arguments to function call, expected 1, have 0}}
+
+  i = __builtin_elementwise_abs(i, i);
+  // expected-error@-1 {{too many arguments to function call, expected 1, have 2}}
+
+  i = __builtin_elementwise_abs(v);
+  // expected-error@-1 {{assigning to 'int' from incompatible type 'float4' (vector of 4 'float' values)}}
+
+  u = __builtin_elementwise_abs(u);
+  // expected-error@-1 {{argument must have a signed integer or floating point type, but was an unsigned integer type}}
+
+  uv = __builtin_elementwise_abs(uv);
+  // expected-error@-1 {{argument must have a signed integer or floating point type, but was an unsigned integer type}}
+}
+
 void test_builtin_elementwise_max(int i, double d, float4 v, int3 iv) {
   i = __builtin_elementwise_max(i, d);
   // expected-error@-1 {{argument types do not match, 'int' != 'double'}}
Index: clang/test/CodeGen/builtins-elementwise-math.c
===
--- clang/test/CodeGen/builtins-elementwise-math.c
+++ clang/test/CodeGen/builtins-elementwise-math.c
@@ -4,12 +4,36 @@
 typedef short int si8 __attribute__((ext_vector_type(8)));
 typedef unsigned int u4 __attribute__((ext_vector_type(4)));
 
+void test_builtin_elementwise_abs(float f1, float f2, double d1, double d2,
+  float4 vf1, float4 vf2, si8 vi1, si8 vi2,
+  long long int i1, long long int i2) {
+  // CHECK-LABEL: define void @test_builtin_elementwise_abs(
+  // CHECK:  [[F1:%.+]] = load float, float* %f1.addr, align 4
+  // CHECK-NEXT:  call float @llvm.fabs.f32(float [[F1]])
+  f2 = __builtin_elementwise_abs(f1);
+
+  // CHECK:  [[D1:%.+]] = load double, double* %d1.addr, align 8
+  // CHECK-NEXT: call double @llvm.fabs.f64(double [[D1]])
+  d2 = __builtin_elementwise_abs(d1);
+
+  // CHECK:  [[VF1:%.+]] = load <4 x float>, <4 x float>* %vf1.addr, align 16
+  // CHECK-NEXT: call <4 x float> @llvm.fabs.v4f32(<4 x float> [[VF1]])
+  vf2 = __builtin_elementwise_abs(vf1);
+
+  // CHECK:  [[I1:%.+]] = load i64, i64* %i1.addr, align 8
+  // CHECK-NEXT: call i64 @llvm.abs.i64(i64 [[I1]], i1 true)
+  i2 = __builtin_elementwise_abs(i1);
+
+  // CHECK:  [[VI1:%.+]] = load <8 x i16>, <8 x i16>* %vi1.addr, align 16
+  // CHECK-NEXT: call <8 x i16> @llvm.abs.v8i16(<8 x i16> [[VI1]], i1 true)
+  vi2 = __builtin_elementwise_abs(vi1);
+}
+
 void test_builtin_elementwise_max(float f1, float f2, double d1, double d2,
   float4 vf1, float4 vf2, long long int i1,
   long long int i2, si8 vi1, si8 vi2,
   unsigned u1, unsigned u2, u4 vu1, u4 vu2) {
   // CHECK-LABEL: define void @test_builtin_elementwise_max(
-
   // CHECK:  [[F1:%.+]] = load float, float* %f1.addr, align 4
   // CHECK-NEXT: [[F2:%.+]] = load float, float* %f2.addr, align 4
   // CHECK-NEXT:  call float @llvm.maxnum.f32(float %0, float %1)
Index: clang/lib/Sema/SemaChecking.cpp
===
--- clang/lib/Sema/SemaChecking.cpp
+++ clang/lib/Sema/SemaChecking.cpp
@@ -1976,9 +1976,12 @@
 break;
   }
 
+  case Builtin::BI__builtin_elementwise_abs:
+return SemaBuiltinElementwiseMathOneArg(TheCall, TheCallResult);
+
   case Builtin::BI__builtin_elementwise_min:
   case Builtin::BI__builtin_elementwise_max:
-return SemaBuiltinElementwiseMath(TheCall, TheCallResult);
+return SemaBuiltinElementwiseMathTwoArgs(TheCall, TheCallResult);
 
   case Builtin::BI__builtin_matrix_tra

[PATCH] D111986: [Clang] Add elementwise abs builtin.

2021-10-19 Thread Florian Hahn via Phabricator via cfe-commits
fhahn marked 2 inline comments as done.
fhahn added inline comments.



Comment at: clang/lib/CodeGen/CGBuiltin.cpp:3109
+  Result = Builder.CreateBinaryIntrinsic(
+  llvm::Intrinsic::abs, Op0, Builder.getFalse(), nullptr, "elt.abs");
+else

craig.topper wrote:
> craig.topper wrote:
> > Did we discuss that this is different than __builtin_abs which is undefined 
> > for INT_MIN?
> I don't think we add nsw to vector signed integer subtract, so I guess using 
> false here is consistent.
> Did we discuss that this is different than __builtin_abs which is undefined 
> for INT_MIN?

So far it was not explicitly called out in the definition. I think we should 
explicitly make it undefined, so I updated the spec in D111529 and passed 
`true` here.


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D111986/new/

https://reviews.llvm.org/D111986

___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D111529: Specify Clang vector builtins.

2021-10-19 Thread Florian Hahn via Phabricator via cfe-commits
fhahn updated this revision to Diff 380755.
fhahn added a comment.

As @scanon pointed out in D111986 , most simd 
implementations should handle abs(INT_MIN) consistently by returngin INT_MIN. 
It's therefore better to avoid defining abs(INT_MIN) as UB, which would make 
the intrinsic more difficult to use. I updated the abs definition to spell out 
the behavior of abs(INT_MIN) as returning INT_MIN.


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D111529/new/

https://reviews.llvm.org/D111529

Files:
  clang/docs/LanguageExtensions.rst


Index: clang/docs/LanguageExtensions.rst
===
--- clang/docs/LanguageExtensions.rst
+++ clang/docs/LanguageExtensions.rst
@@ -506,6 +506,83 @@
   If it's an extension (OpenCL) vector, it's only available in C and OpenCL C.
   And it selects base on signedness of the condition operands (OpenCL v1.1 
s6.3.9).
 
+Vector Builtins
+---
+
+**Note: The implementation of vector builtins is work-in-progress and 
incomplete.**
+
+In addition to the operators mentioned above, Clang provides a set of builtins
+to perform additional operations on certain scalar and vector types.
+
+Let ``T`` be one of the following types:
+
+* an integer type (as in C2x 6.2.5p19), but excluding enumerated types and 
_Bool
+* the standard floating types float or double
+* a half-precision floating point type, if one is supported on the target
+* a vector type.
+
+For scalar types, consider the operation applied to a vector with a single 
element.
+
+*Elementwise Builtins*
+
+Each builtin returns a vector equivalent to applying the specified operation
+elementwise to the input.
+
+Unless specified otherwise operation(±0) = ±0 and operation(±infinity) = 
±infinity
+
+= 
 
=
+ Name  Operation   
 Supported element types
+= 
 
=
+ T __builtin_elementwise_abs(T x)  return the absolute value of a 
number x; the absolute value of   signed integer and floating point types
+   the most negative integer remains 
the most negative integer
+ T __builtin_elementwise_ceil(T x) return the smallest integral value 
greater than or equal to xfloating point types
+ T __builtin_elementwise_floor(T x)return the largest integral value 
less than or equal to xfloating point types
+ T __builtin_elementwise_roundeven(T x)round x to the nearest integer 
value in floating point format,   floating point types
+   rounding halfway cases to even 
(that is, to the nearest value
+   that is an even integer), 
regardless of the current rounding
+   direction.
+ T__builtin_elementwise_trunc(T x) return the integral value nearest 
to but no larger infloating point types
+   magnitude than x
+ T __builtin_elementwise_max(T x, T y) return x or y, whichever is larger  
 integer and floating point types
+ T __builtin_elementwise_min(T x, T y) return x or y, whichever is smaller 
 integer and floating point types
+= 
 
=
+
+
+*Reduction Builtins*
+
+Each builtin returns a scalar equivalent to applying the specified
+operation(x, y) as recursive even-odd pairwise reduction to all vector
+elements. ``operation(x, y)`` is repeatedly applied to each non-overlapping
+even-odd element pair with indices ``i * 2`` and ``i * 2 + 1`` with
+``i in [0, Number of elements / 2)``. If the numbers of elements is not a
+power of 2, the vector is widened with neutral elements for the reduction
+at the end to the next power of 2.
+
+Example:
+
+.. code-block:: c++
+
+__builtin_reduce_add([e3, e2, e1, e0]) = __builtin_reduced_add([e3 + e2, 
e1 + e0])
+   = (e3 + e2) + (e1 + e0)
+
+
+Let ``VT`` be a vector type and ``ET`` the element type of ``VT``.
+
+=== 
 
==
+ NameOperation 
   Supported element types
+=== 
 
=

[PATCH] D111986: [Clang] Add elementwise abs builtin.

2021-10-19 Thread Florian Hahn via Phabricator via cfe-commits
fhahn updated this revision to Diff 380756.
fhahn added a comment.

In D111986#3072946 , @scanon wrote:

> What's the rationale for making abs undefined on the minimum value? AFAIK 
> every actual simd implementation defines the result and they agree (and even 
> if one didn't, it would be pretty easy to get the "right" result. Introducing 
> UB here just seems like punishing users for no reason.

Thanks! As making it UB does not really help with lowering I went back to 
allowing INT_MIN and updated the spec to explicitly spell out the behavior.


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D111986/new/

https://reviews.llvm.org/D111986

Files:
  clang/include/clang/Basic/Builtins.def
  clang/include/clang/Basic/DiagnosticSemaKinds.td
  clang/include/clang/Sema/Sema.h
  clang/lib/CodeGen/CGBuiltin.cpp
  clang/lib/Sema/SemaChecking.cpp
  clang/test/CodeGen/builtins-elementwise-math.c
  clang/test/Sema/builtins-elementwise-math.c

Index: clang/test/Sema/builtins-elementwise-math.c
===
--- clang/test/Sema/builtins-elementwise-math.c
+++ clang/test/Sema/builtins-elementwise-math.c
@@ -2,11 +2,32 @@
 
 typedef float float4 __attribute__((ext_vector_type(4)));
 typedef int int3 __attribute__((ext_vector_type(3)));
+typedef unsigned unsigned4 __attribute__((ext_vector_type(4)));
 
 struct Foo {
   char *p;
 };
 
+void test_builtin_elementwise_abs(int i, double d, float4 v, int3 iv, unsigned u, unsigned4 uv) {
+  struct Foo s = __builtin_elementwise_abs(i);
+  // expected-error@-1 {{initializing 'struct Foo' with an expression of incompatible type 'int'}}
+
+  i = __builtin_elementwise_abs();
+  // expected-error@-1 {{too few arguments to function call, expected 1, have 0}}
+
+  i = __builtin_elementwise_abs(i, i);
+  // expected-error@-1 {{too many arguments to function call, expected 1, have 2}}
+
+  i = __builtin_elementwise_abs(v);
+  // expected-error@-1 {{assigning to 'int' from incompatible type 'float4' (vector of 4 'float' values)}}
+
+  u = __builtin_elementwise_abs(u);
+  // expected-error@-1 {{argument must have a signed integer or floating point type, but was an unsigned integer type}}
+
+  uv = __builtin_elementwise_abs(uv);
+  // expected-error@-1 {{argument must have a signed integer or floating point type, but was an unsigned integer type}}
+}
+
 void test_builtin_elementwise_max(int i, double d, float4 v, int3 iv) {
   i = __builtin_elementwise_max(i, d);
   // expected-error@-1 {{argument types do not match, 'int' != 'double'}}
Index: clang/test/CodeGen/builtins-elementwise-math.c
===
--- clang/test/CodeGen/builtins-elementwise-math.c
+++ clang/test/CodeGen/builtins-elementwise-math.c
@@ -4,12 +4,36 @@
 typedef short int si8 __attribute__((ext_vector_type(8)));
 typedef unsigned int u4 __attribute__((ext_vector_type(4)));
 
+void test_builtin_elementwise_abs(float f1, float f2, double d1, double d2,
+  float4 vf1, float4 vf2, si8 vi1, si8 vi2,
+  long long int i1, long long int i2) {
+  // CHECK-LABEL: define void @test_builtin_elementwise_abs(
+  // CHECK:  [[F1:%.+]] = load float, float* %f1.addr, align 4
+  // CHECK-NEXT:  call float @llvm.fabs.f32(float [[F1]])
+  f2 = __builtin_elementwise_abs(f1);
+
+  // CHECK:  [[D1:%.+]] = load double, double* %d1.addr, align 8
+  // CHECK-NEXT: call double @llvm.fabs.f64(double [[D1]])
+  d2 = __builtin_elementwise_abs(d1);
+
+  // CHECK:  [[VF1:%.+]] = load <4 x float>, <4 x float>* %vf1.addr, align 16
+  // CHECK-NEXT: call <4 x float> @llvm.fabs.v4f32(<4 x float> [[VF1]])
+  vf2 = __builtin_elementwise_abs(vf1);
+
+  // CHECK:  [[I1:%.+]] = load i64, i64* %i1.addr, align 8
+  // CHECK-NEXT: call i64 @llvm.abs.i64(i64 [[I1]], i1 false)
+  i2 = __builtin_elementwise_abs(i1);
+
+  // CHECK:  [[VI1:%.+]] = load <8 x i16>, <8 x i16>* %vi1.addr, align 16
+  // CHECK-NEXT: call <8 x i16> @llvm.abs.v8i16(<8 x i16> [[VI1]], i1 false)
+  vi2 = __builtin_elementwise_abs(vi1);
+}
+
 void test_builtin_elementwise_max(float f1, float f2, double d1, double d2,
   float4 vf1, float4 vf2, long long int i1,
   long long int i2, si8 vi1, si8 vi2,
   unsigned u1, unsigned u2, u4 vu1, u4 vu2) {
   // CHECK-LABEL: define void @test_builtin_elementwise_max(
-
   // CHECK:  [[F1:%.+]] = load float, float* %f1.addr, align 4
   // CHECK-NEXT: [[F2:%.+]] = load float, float* %f2.addr, align 4
   // CHECK-NEXT:  call float @llvm.maxnum.f32(float %0, float %1)
Index: clang/lib/Sema/SemaChecking.cpp
===
--- clang/lib/Sema/SemaChecking.cpp
+++ clang/lib/Sema/SemaChecking.cpp
@@ -1976,9 +1976,12 @@
 break;
   }
 
+  cas

[PATCH] D111985: [Clang] Add elementwise min/max builtins.

2021-10-20 Thread Florian Hahn via Phabricator via cfe-commits
fhahn updated this revision to Diff 380946.
fhahn added a comment.

Move type checking to helper function checkMathBuiltinElementType to be reused 
in D111986 .


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D111985/new/

https://reviews.llvm.org/D111985

Files:
  clang/include/clang/Basic/Builtins.def
  clang/include/clang/Basic/DiagnosticSemaKinds.td
  clang/include/clang/Sema/Sema.h
  clang/lib/CodeGen/CGBuiltin.cpp
  clang/lib/Sema/SemaChecking.cpp
  clang/test/CodeGen/builtins-elementwise-math.c
  clang/test/Sema/builtins-elementwise-math.c

Index: clang/test/Sema/builtins-elementwise-math.c
===
--- /dev/null
+++ clang/test/Sema/builtins-elementwise-math.c
@@ -0,0 +1,42 @@
+// RUN: %clang_cc1 %s -pedantic -verify -triple=x86_64-apple-darwin9
+
+typedef float float4 __attribute__((ext_vector_type(4)));
+typedef int int3 __attribute__((ext_vector_type(3)));
+
+struct Foo {
+  char *p;
+};
+
+void test_builtin_elementwise_max(int i, double d, float4 v, int3 iv) {
+  i = __builtin_elementwise_max(i, d);
+  // expected-error@-1 {{argument types do not match, 'int' != 'double'}}
+
+  struct Foo s = __builtin_elementwise_max(i, i);
+  // expected-error@-1 {{initializing 'struct Foo' with an expression of incompatible type 'int'}}
+
+  i = __builtin_elementwise_max(i);
+  // expected-error@-1 {{too few arguments to function call, expected 2, have 1}}
+
+  i = __builtin_elementwise_max();
+  // expected-error@-1 {{too few arguments to function call, expected 2, have 0}}
+
+  i = __builtin_elementwise_max(v, iv);
+  // expected-error@-1 {{argument types do not match, 'float4' (vector of 4 'float' values) != 'int3' (vector of 3 'int' values)}}
+}
+
+void test_builtin_elementwise_min(int i, double d, float4 v, int3 iv) {
+  i = __builtin_elementwise_min(i, d);
+  // expected-error@-1 {{argument types do not match, 'int' != 'double'}}
+
+  struct Foo s = __builtin_elementwise_min(i, i);
+  // expected-error@-1 {{initializing 'struct Foo' with an expression of incompatible type 'int'}}
+
+  i = __builtin_elementwise_min(i);
+  // expected-error@-1 {{too few arguments to function call, expected 2, have 1}}
+
+  i = __builtin_elementwise_min();
+  // expected-error@-1 {{too few arguments to function call, expected 2, have 0}}
+
+  i = __builtin_elementwise_min(v, iv);
+  // expected-error@-1 {{argument types do not match, 'float4' (vector of 4 'float' values) != 'int3' (vector of 3 'int' values)}}
+}
Index: clang/test/CodeGen/builtins-elementwise-math.c
===
--- /dev/null
+++ clang/test/CodeGen/builtins-elementwise-math.c
@@ -0,0 +1,88 @@
+// RUN: %clang_cc1 -triple x86_64-apple-darwin %s -emit-llvm -disable-llvm-passes -o - | FileCheck %s
+
+typedef float float4 __attribute__((ext_vector_type(4)));
+typedef short int si8 __attribute__((ext_vector_type(8)));
+typedef unsigned int u4 __attribute__((ext_vector_type(4)));
+
+void test_builtin_elementwise_max(float f1, float f2, double d1, double d2,
+  float4 vf1, float4 vf2, long long int i1,
+  long long int i2, si8 vi1, si8 vi2,
+  unsigned u1, unsigned u2, u4 vu1, u4 vu2) {
+  // CHECK-LABEL: define void @test_builtin_elementwise_max(
+
+  // CHECK:  [[F1:%.+]] = load float, float* %f1.addr, align 4
+  // CHECK-NEXT: [[F2:%.+]] = load float, float* %f2.addr, align 4
+  // CHECK-NEXT:  call float @llvm.maxnum.f32(float %0, float %1)
+  f1 = __builtin_elementwise_max(f1, f2);
+
+  // CHECK:  [[D1:%.+]] = load double, double* %d1.addr, align 8
+  // CHECK-NEXT: [[D2:%.+]] = load double, double* %d2.addr, align 8
+  // CHECK-NEXT: call double @llvm.maxnum.f64(double [[D1]], double [[D2]])
+  d1 = __builtin_elementwise_max(d1, d2);
+
+  // CHECK:  [[VF1:%.+]] = load <4 x float>, <4 x float>* %vf1.addr, align 16
+  // CHECK-NEXT: [[VF2:%.+]] = load <4 x float>, <4 x float>* %vf2.addr, align 16
+  // CHECK-NEXT: call <4 x float> @llvm.maxnum.v4f32(<4 x float> [[VF1]], <4 x float> [[VF2]])
+  vf1 = __builtin_elementwise_max(vf1, vf2);
+
+  // CHECK:  [[I1:%.+]] = load i64, i64* %i1.addr, align 8
+  // CHECK-NEXT: [[I2:%.+]] = load i64, i64* %i2.addr, align 8
+  // CHECK-NEXT: call i64 @llvm.smax.i64(i64 [[I1]], i64 [[I2]])
+  i1 = __builtin_elementwise_max(i1, i2);
+
+  // CHECK:  [[VI1:%.+]] = load <8 x i16>, <8 x i16>* %vi1.addr, align 16
+  // CHECK-NEXT: [[VI2:%.+]] = load <8 x i16>, <8 x i16>* %vi2.addr, align 16
+  // CHECK-NEXT: call <8 x i16> @llvm.smax.v8i16(<8 x i16> [[VI1]], <8 x i16> [[VI2]])
+  vi1 = __builtin_elementwise_max(vi1, vi2);
+
+  // CHECK:  [[U1:%.+]] = load i32, i32* %u1.addr, align 4
+  // CHECK-NEXT: [[U2:%.+]] = load i32, i32* %u2.addr, align 4
+  // CHECK-NEXT: call i32 @llvm.umax.i32(i32 [[U1]], i32 [[U2]])
+  u1 = __buil

[PATCH] D111986: [Clang] Add elementwise abs builtin.

2021-10-20 Thread Florian Hahn via Phabricator via cfe-commits
fhahn updated this revision to Diff 380947.
fhahn added a comment.

Use checkMathBuiltinElementType helper added in D111985 
.


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D111986/new/

https://reviews.llvm.org/D111986

Files:
  clang/include/clang/Basic/Builtins.def
  clang/include/clang/Basic/DiagnosticSemaKinds.td
  clang/include/clang/Sema/Sema.h
  clang/lib/CodeGen/CGBuiltin.cpp
  clang/lib/Sema/SemaChecking.cpp
  clang/test/CodeGen/builtins-elementwise-math.c
  clang/test/Sema/builtins-elementwise-math.c

Index: clang/test/Sema/builtins-elementwise-math.c
===
--- clang/test/Sema/builtins-elementwise-math.c
+++ clang/test/Sema/builtins-elementwise-math.c
@@ -2,11 +2,32 @@
 
 typedef float float4 __attribute__((ext_vector_type(4)));
 typedef int int3 __attribute__((ext_vector_type(3)));
+typedef unsigned unsigned4 __attribute__((ext_vector_type(4)));
 
 struct Foo {
   char *p;
 };
 
+void test_builtin_elementwise_abs(int i, double d, float4 v, int3 iv, unsigned u, unsigned4 uv) {
+  struct Foo s = __builtin_elementwise_abs(i);
+  // expected-error@-1 {{initializing 'struct Foo' with an expression of incompatible type 'int'}}
+
+  i = __builtin_elementwise_abs();
+  // expected-error@-1 {{too few arguments to function call, expected 1, have 0}}
+
+  i = __builtin_elementwise_abs(i, i);
+  // expected-error@-1 {{too many arguments to function call, expected 1, have 2}}
+
+  i = __builtin_elementwise_abs(v);
+  // expected-error@-1 {{assigning to 'int' from incompatible type 'float4' (vector of 4 'float' values)}}
+
+  u = __builtin_elementwise_abs(u);
+  // expected-error@-1 {{argument must have a signed integer or floating point type, but was an unsigned integer type}}
+
+  uv = __builtin_elementwise_abs(uv);
+  // expected-error@-1 {{argument must have a signed integer or floating point type, but was an unsigned integer type}}
+}
+
 void test_builtin_elementwise_max(int i, double d, float4 v, int3 iv) {
   i = __builtin_elementwise_max(i, d);
   // expected-error@-1 {{argument types do not match, 'int' != 'double'}}
Index: clang/test/CodeGen/builtins-elementwise-math.c
===
--- clang/test/CodeGen/builtins-elementwise-math.c
+++ clang/test/CodeGen/builtins-elementwise-math.c
@@ -4,12 +4,36 @@
 typedef short int si8 __attribute__((ext_vector_type(8)));
 typedef unsigned int u4 __attribute__((ext_vector_type(4)));
 
+void test_builtin_elementwise_abs(float f1, float f2, double d1, double d2,
+  float4 vf1, float4 vf2, si8 vi1, si8 vi2,
+  long long int i1, long long int i2) {
+  // CHECK-LABEL: define void @test_builtin_elementwise_abs(
+  // CHECK:  [[F1:%.+]] = load float, float* %f1.addr, align 4
+  // CHECK-NEXT:  call float @llvm.fabs.f32(float [[F1]])
+  f2 = __builtin_elementwise_abs(f1);
+
+  // CHECK:  [[D1:%.+]] = load double, double* %d1.addr, align 8
+  // CHECK-NEXT: call double @llvm.fabs.f64(double [[D1]])
+  d2 = __builtin_elementwise_abs(d1);
+
+  // CHECK:  [[VF1:%.+]] = load <4 x float>, <4 x float>* %vf1.addr, align 16
+  // CHECK-NEXT: call <4 x float> @llvm.fabs.v4f32(<4 x float> [[VF1]])
+  vf2 = __builtin_elementwise_abs(vf1);
+
+  // CHECK:  [[I1:%.+]] = load i64, i64* %i1.addr, align 8
+  // CHECK-NEXT: call i64 @llvm.abs.i64(i64 [[I1]], i1 false)
+  i2 = __builtin_elementwise_abs(i1);
+
+  // CHECK:  [[VI1:%.+]] = load <8 x i16>, <8 x i16>* %vi1.addr, align 16
+  // CHECK-NEXT: call <8 x i16> @llvm.abs.v8i16(<8 x i16> [[VI1]], i1 false)
+  vi2 = __builtin_elementwise_abs(vi1);
+}
+
 void test_builtin_elementwise_max(float f1, float f2, double d1, double d2,
   float4 vf1, float4 vf2, long long int i1,
   long long int i2, si8 vi1, si8 vi2,
   unsigned u1, unsigned u2, u4 vu1, u4 vu2) {
   // CHECK-LABEL: define void @test_builtin_elementwise_max(
-
   // CHECK:  [[F1:%.+]] = load float, float* %f1.addr, align 4
   // CHECK-NEXT: [[F2:%.+]] = load float, float* %f2.addr, align 4
   // CHECK-NEXT:  call float @llvm.maxnum.f32(float %0, float %1)
Index: clang/lib/Sema/SemaChecking.cpp
===
--- clang/lib/Sema/SemaChecking.cpp
+++ clang/lib/Sema/SemaChecking.cpp
@@ -1976,9 +1976,12 @@
 break;
   }
 
+  case Builtin::BI__builtin_elementwise_abs:
+return SemaBuiltinElementwiseMathOneArg(TheCall, TheCallResult);
+
   case Builtin::BI__builtin_elementwise_min:
   case Builtin::BI__builtin_elementwise_max:
-return SemaBuiltinElementwiseMath(TheCall, TheCallResult);
+return SemaBuiltinElementwiseMathTwoArgs(TheCall, TheCallResult);
 
   case Builtin::BI__builtin_matrix_transpose:
 return SemaBuiltinMatrixTranspose(TheCal

[PATCH] D112001: [Clang] Add min/max reduction builtins.

2021-10-20 Thread Florian Hahn via Phabricator via cfe-commits
fhahn updated this revision to Diff 380948.
fhahn marked an inline comment as done.
fhahn added a comment.

rebase on top of recently updated patches.


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D112001/new/

https://reviews.llvm.org/D112001

Files:
  clang/include/clang/Basic/Builtins.def
  clang/include/clang/Sema/Sema.h
  clang/lib/CodeGen/CGBuiltin.cpp
  clang/lib/Sema/SemaChecking.cpp
  clang/test/CodeGen/builtins-elementwise-math.c
  clang/test/Sema/builtins-elementwise-math.c

Index: clang/test/Sema/builtins-elementwise-math.c
===
--- clang/test/Sema/builtins-elementwise-math.c
+++ clang/test/Sema/builtins-elementwise-math.c
@@ -61,3 +61,31 @@
   i = __builtin_elementwise_min(v, iv);
   // expected-error@-1 {{argument types do not match, 'float4' (vector of 4 'float' values) != 'int3' (vector of 3 'int' values)}}
 }
+
+void test_builtin_reduce_max(int i, float4 v, int3 iv) {
+  struct Foo s = __builtin_reduce_max(iv);
+  // expected-error@-1 {{initializing 'struct Foo' with an expression of incompatible type 'int'}}
+
+  i = __builtin_reduce_max(v, v);
+  // expected-error@-1 {{too many arguments to function call, expected 1, have 2}}
+
+  i = __builtin_reduce_max();
+  // expected-error@-1 {{too few arguments to function call, expected 1, have 0}}
+
+  i = __builtin_reduce_max(i);
+  // expected-error@-1 {{argument must have a vector type, but was 'int'}}
+}
+
+void test_builtin_reduce_min(int i, float4 v, int3 iv) {
+  struct Foo s = __builtin_reduce_min(iv);
+  // expected-error@-1 {{initializing 'struct Foo' with an expression of incompatible type 'int'}}
+
+  i = __builtin_reduce_min(v, v);
+  // expected-error@-1 {{too many arguments to function call, expected 1, have 2}}
+
+  i = __builtin_reduce_min();
+  // expected-error@-1 {{too few arguments to function call, expected 1, have 0}}
+
+  i = __builtin_reduce_min(i);
+  // expected-error@-1 {{argument must have a vector type, but was 'int'}}
+}
Index: clang/test/CodeGen/builtins-elementwise-math.c
===
--- clang/test/CodeGen/builtins-elementwise-math.c
+++ clang/test/CodeGen/builtins-elementwise-math.c
@@ -110,3 +110,33 @@
   // CHECK-NEXT: call <4 x i32> @llvm.umin.v4i32(<4 x i32> [[VU1]], <4 x i32> [[VU2]])
   vu1 = __builtin_elementwise_min(vu1, vu2);
 }
+
+void test_builtin_reduce_max(float4 vf1, si8 vi1, u4 vu1) {
+  // CHECK-LABEL: define void @test_builtin_reduce_max(
+  // CHECK:  [[VF1:%.+]] = load <4 x float>, <4 x float>* %vf1.addr, align 16
+  // CHECK-NEXT: call float @llvm.vector.reduce.fmax.v4f32(<4 x float> [[VF1]])
+  float r1 = __builtin_reduce_max(vf1);
+
+  // CHECK:  [[VI1:%.+]] = load <8 x i16>, <8 x i16>* %vi1.addr, align 16
+  // CHECK-NEXT: call i16 @llvm.vector.reduce.smax.v8i16(<8 x i16> [[VI1]])
+  short r2 = __builtin_reduce_max(vi1);
+
+  // CHECK:  [[VU1:%.+]] = load <4 x i32>, <4 x i32>* %vu1.addr, align 16
+  // CHECK-NEXT: call i32 @llvm.vector.reduce.umax.v4i32(<4 x i32> [[VU1]])
+  unsigned r3 = __builtin_reduce_max(vu1);
+}
+
+void test_builtin_reduce_min(float4 vf1, si8 vi1, u4 vu1) {
+  // CHECK-LABEL: define void @test_builtin_reduce_min(
+  // CHECK:  [[VF1:%.+]] = load <4 x float>, <4 x float>* %vf1.addr, align 16
+  // CHECK-NEXT: call float @llvm.vector.reduce.fmin.v4f32(<4 x float> [[VF1]])
+  float r1 = __builtin_reduce_min(vf1);
+
+  // CHECK:  [[VI1:%.+]] = load <8 x i16>, <8 x i16>* %vi1.addr, align 16
+  // CHECK-NEXT: call i16 @llvm.vector.reduce.smin.v8i16(<8 x i16> [[VI1]])
+  short r2 = __builtin_reduce_min(vi1);
+
+  // CHECK:  [[VU1:%.+]] = load <4 x i32>, <4 x i32>* %vu1.addr, align 16
+  // CHECK-NEXT: call i32 @llvm.vector.reduce.umin.v4i32(<4 x i32> [[VU1]])
+  unsigned r3 = __builtin_reduce_min(vu1);
+}
Index: clang/lib/Sema/SemaChecking.cpp
===
--- clang/lib/Sema/SemaChecking.cpp
+++ clang/lib/Sema/SemaChecking.cpp
@@ -1978,11 +1978,14 @@
 
   case Builtin::BI__builtin_elementwise_abs:
 return SemaBuiltinElementwiseMathOneArg(TheCall, TheCallResult);
-
   case Builtin::BI__builtin_elementwise_min:
   case Builtin::BI__builtin_elementwise_max:
 return SemaBuiltinElementwiseMathTwoArgs(TheCall, TheCallResult);
 
+  case Builtin::BI__builtin_reduce_max:
+  case Builtin::BI__builtin_reduce_min:
+return SemaBuiltinReduceMath(TheCall, TheCallResult);
+
   case Builtin::BI__builtin_matrix_transpose:
 return SemaBuiltinMatrixTranspose(TheCall, TheCallResult);
   case Builtin::BI__builtin_matrix_column_major_load:
@@ -16712,6 +16715,23 @@
   return CallResult;
 }
 
+ExprResult Sema::SemaBuiltinReduceMath(CallExpr *TheCall,
+   ExprResult CallResult) {
+  if (checkArgCount(*this, TheCall, 1))
+return ExprError();
+
+  Expr *A = TheCall->getArg(0);
+  QualType TyA = A->getType

[PATCH] D111986: [Clang] Add elementwise abs builtin.

2021-10-20 Thread Florian Hahn via Phabricator via cfe-commits
fhahn marked 2 inline comments as done.
fhahn added inline comments.



Comment at: clang/lib/Sema/SemaChecking.cpp:16667
+
+  if (!TyA->getAs() && 
!ConstantMatrixType::isValidElementType(TyA))
+return Diag(A->getBeginLoc(), diag::err_elementwise_math_invalid_arg_type)

scanon wrote:
> Given that I expect this particular test to occur fairly frequently, maybe 
> worth abstracting into some sort of get-elementwise-type operation.
moved out to a helper in the previous patch in the series, D111985



Comment at: clang/test/Sema/builtins-elementwise-math.c:25
+  u = __builtin_elementwise_abs(u);
+  // expected-error@-1 {{argument must have a signed integer or floating point 
type, but was an unsigned integer type}}
+

scanon wrote:
> For the purposes of C++ templates it might be nice to allow `abs` on unsigned 
> (as the identity function). I don't have strong feelings though, and a 
> library wrapping the builtins can do this themselves.
yeah that would be an option. I don't have any strong feelings either


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D111986/new/

https://reviews.llvm.org/D111986

___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D111985: [Clang] Add elementwise min/max builtins.

2021-10-25 Thread Florian Hahn via Phabricator via cfe-commits
fhahn added a comment.

ping :)


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D111985/new/

https://reviews.llvm.org/D111985

___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D111985: [Clang] Add elementwise min/max builtins.

2021-10-25 Thread Florian Hahn via Phabricator via cfe-commits
fhahn marked 5 inline comments as done.
fhahn added a comment.

Thanks for taking a look!




Comment at: clang/lib/Sema/SemaChecking.cpp:16659-16660
+// false.
+static bool checkMathBuiltinElementType(SourceLocation Loc, QualType Ty,
+Sema &S) {
+  if (!Ty->getAs() && !ConstantMatrixType::isValidElementType(Ty)) 
{

aaron.ballman wrote:
> `Sema` typically comes first, so this is just to match local style.
Thanks, adjusted!



Comment at: clang/lib/Sema/SemaChecking.cpp:16661
+Sema &S) {
+  if (!Ty->getAs() && !ConstantMatrixType::isValidElementType(Ty)) 
{
+S.Diag(Loc, diag::err_elementwise_math_invalid_arg_type) << Ty;

aaron.ballman wrote:
> I'm a bit surprised we'd need `!Ty->getAs()` as I would have 
> expected `!ConstantMatrixType::isValidElementType(Ty)` to cover all the type 
> checking of `Ty`. Can you explain why the extra check is needed here?
The builtins as implemented accept either vector types or a scalar type, which 
then must be a valid element type for matrix types. The second check may be a 
bit confusing, but the restrictions laid out in the spec for 
scalar/element-types match the matrix element type restrictions, so this seems 
a convenient helper to use.

Does this in general make sense?



Comment at: clang/lib/Sema/SemaChecking.cpp:16669
+ExprResult Sema::SemaBuiltinElementwiseMath(CallExpr *TheCall,
+ExprResult CallResult) {
+  if (checkArgCount(*this, TheCall, 2))

aaron.ballman wrote:
> Do we actually need this parameter?
No, it can just return `ExprResult(TheCall)` instead I think!



Comment at: clang/lib/Sema/SemaChecking.cpp:16673-16678
+  Expr *A = TheCall->getArg(0);
+  Expr *B = TheCall->getArg(1);
+  QualType TyA = A->getType();
+  QualType TyB = B->getType();
+
+  if (TyA != TyB)

aaron.ballman wrote:
> Should these arguments undergo usual conversions (array to pointer decay, 
> integer promotions, etc)?
I intentionally went with not performing conversions, because it might lead to 
surprising results. If the arguments have different types, it is not clear to 
me which type should be chosen to try convert the other one; e.g. if we have 
__builtin_elementwise_max(float, int)` should the first argument be converted 
to `int` or the second one to `float`?

Forcing the types to match without conversion seem to make them less 
error-prone to use, but I might be missing some general rule to handle type 
conflicts here?



Comment at: clang/test/Sema/builtins-elementwise-math.c:20-21
+
+  i = __builtin_elementwise_max();
+  // expected-error@-1 {{too few arguments to function call, expected 2, have 
0}}
+

aaron.ballman wrote:
> Also:
> ```
> i = __builtin_elementwise_max(i, i, i); // too many arguments
> ```
I'll add it



Comment at: clang/test/Sema/builtins-elementwise-math.c:42
+  // expected-error@-1 {{argument types do not match, 'float4' (vector of 4 
'float' values) != 'int3' (vector of 3 'int' values)}}
+}

aaron.ballman wrote:
> Additional tests I would like to see:
> ```
> int i;
> short s;
> 
> __builtin_elementwise_min(i, s); // ok (integer promotions)?
> 
> enum e { one, two };
> __builtin_elementwise_min(one, two); // ok (using enums)?
> 
> enum f { three };
> __builtin_elementwise_min(one, three); // ok (different enums)?
> 
> _ExtInt(32) ext;
> __builtin_elementwise_min(ext, ext); // ok (using bit-precise integers)?
> 
> const int ci;
> __builtin_elementwise_min(i, ci); // ok (qualifiers don't match)?
> ```
Thanks I'll add those!

at the moment `__builtin_elementwise_min(i, s); // ok (integer promotions)?` 
would be rejected, as per my response in Sema.

The other currently are not handled properly, which I'll fix!


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D111985/new/

https://reviews.llvm.org/D111985

___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D111985: [Clang] Add elementwise min/max builtins.

2021-10-25 Thread Florian Hahn via Phabricator via cfe-commits
fhahn marked 6 inline comments as done.
fhahn added inline comments.



Comment at: clang/lib/Sema/SemaChecking.cpp:16673-16678
+  Expr *A = TheCall->getArg(0);
+  Expr *B = TheCall->getArg(1);
+  QualType TyA = A->getType();
+  QualType TyB = B->getType();
+
+  if (TyA != TyB)

aaron.ballman wrote:
> fhahn wrote:
> > aaron.ballman wrote:
> > > Should these arguments undergo usual conversions (array to pointer decay, 
> > > integer promotions, etc)?
> > I intentionally went with not performing conversions, because it might lead 
> > to surprising results. If the arguments have different types, it is not 
> > clear to me which type should be chosen to try convert the other one; e.g. 
> > if we have __builtin_elementwise_max(float, int)` should the first argument 
> > be converted to `int` or the second one to `float`?
> > 
> > Forcing the types to match without conversion seem to make them less 
> > error-prone to use, but I might be missing some general rule to handle type 
> > conflicts here?
> I'm not certain how these builtins are expected to be used, but if they're 
> likely to be used with literals, I think we may want integer promotions 
> because of that alone.
> 
> Btw, given that these only have two arguments, it seems like we could use the 
> usual arithmetic conversions to pick a common type the same way as happens 
> for binary operators.
> 
> If you end up not adding any conversions here, we should have a test case to 
> cover passing in two array objects (which won't decay to pointers).
> I'm not certain how these builtins are expected to be used, but if they're 
> likely to be used with literals, I think we may want integer promotions 
> because of that alone.

Yes, they should ideally work with literals! I think it should be relatively 
straight-forward to add promotion of literals.

> Btw, given that these only have two arguments, it seems like we could use the 
> usual arithmetic conversions to pick a common type the same way as happens 
> for binary operators.

IIUC this happens in `SemaOverload.cpp`, but I am not sure how builtins would 
hook into the infrastructure there. Are there other builtins that are similarly 
overloaded by any chance?


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D111985/new/

https://reviews.llvm.org/D111985

___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D111985: [Clang] Add elementwise min/max builtins.

2021-10-25 Thread Florian Hahn via Phabricator via cfe-commits
fhahn updated this revision to Diff 382128.
fhahn marked an inline comment as done.
fhahn added a comment.

Address comments @aaron.ballman, thanks!

The most notable changes are using `UsualArithmeticConversions` for argument 
conversion and checking the canonical types. Also added a bunch of additional 
Sema tests as suggested, and some codegen tests for a couple of conversions.


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D111985/new/

https://reviews.llvm.org/D111985

Files:
  clang/include/clang/Basic/Builtins.def
  clang/include/clang/Basic/DiagnosticSemaKinds.td
  clang/include/clang/Sema/Sema.h
  clang/lib/CodeGen/CGBuiltin.cpp
  clang/lib/Sema/SemaChecking.cpp
  clang/test/CodeGen/builtins-elementwise-math.c
  clang/test/Sema/builtins-elementwise-math.c

Index: clang/test/Sema/builtins-elementwise-math.c
===
--- /dev/null
+++ clang/test/Sema/builtins-elementwise-math.c
@@ -0,0 +1,102 @@
+// RUN: %clang_cc1 %s -pedantic -verify -triple=x86_64-apple-darwin9
+
+typedef float float4 __attribute__((ext_vector_type(4)));
+typedef int int3 __attribute__((ext_vector_type(3)));
+
+struct Foo {
+  char *p;
+};
+
+__attribute__((address_space(1))) int int_as_one;
+typedef int bar;
+bar b;
+
+void test_builtin_elementwise_max(int i, short s, double d, float4 v, int3 iv, int *p) {
+  i = __builtin_elementwise_max(p, d);
+  // expected-error@-1 {{argument types do not match, 'int *' != 'double'}}
+
+  struct Foo foo = __builtin_elementwise_max(i, i);
+  // expected-error@-1 {{initializing 'struct Foo' with an expression of incompatible type 'int'}}
+
+  i = __builtin_elementwise_max(i);
+  // expected-error@-1 {{too few arguments to function call, expected 2, have 1}}
+
+  i = __builtin_elementwise_max();
+  // expected-error@-1 {{too few arguments to function call, expected 2, have 0}}
+
+  i = __builtin_elementwise_max(v, iv);
+  // expected-error@-1 {{argument types do not match, 'float4' (vector of 4 'float' values) != 'int3' (vector of 3 'int' values)}}
+
+  s = __builtin_elementwise_max(i, s);
+
+  enum e { one,
+   two };
+  i = __builtin_elementwise_max(one, two);
+
+  enum f { three };
+  enum f x = __builtin_elementwise_max(one, three);
+
+  _ExtInt(32) ext;
+  ext = __builtin_elementwise_max(ext, ext);
+
+  const int ci;
+  i = __builtin_elementwise_max(ci, i);
+  i = __builtin_elementwise_max(i, ci);
+  i = __builtin_elementwise_max(ci, ci);
+
+  i = __builtin_elementwise_max(i, int_as_one); // ok (attributes don't match)?
+  i = __builtin_elementwise_max(i, b);  // ok (sugar doesn't match)?
+
+  int A[10];
+  A = __builtin_elementwise_max(A, A);
+  // expected-error@-1 {{argument type 'int *' is not supported}}
+
+  int(ii);
+  int j;
+  j = __builtin_elementwise_max(i, j);
+}
+
+void test_builtin_elementwise_min(int i, short s, double d, float4 v, int3 iv, int *p) {
+  i = __builtin_elementwise_min(p, d);
+  // expected-error@-1 {{argument types do not match, 'int *' != 'double'}}
+
+  struct Foo foo = __builtin_elementwise_min(i, i);
+  // expected-error@-1 {{initializing 'struct Foo' with an expression of incompatible type 'int'}}
+
+  i = __builtin_elementwise_min(i);
+  // expected-error@-1 {{too few arguments to function call, expected 2, have 1}}
+
+  i = __builtin_elementwise_min();
+  // expected-error@-1 {{too few arguments to function call, expected 2, have 0}}
+
+  i = __builtin_elementwise_min(v, iv);
+  // expected-error@-1 {{argument types do not match, 'float4' (vector of 4 'float' values) != 'int3' (vector of 3 'int' values)}}
+
+  s = __builtin_elementwise_min(i, s);
+
+  enum e { one,
+   two };
+  i = __builtin_elementwise_min(one, two);
+
+  enum f { three };
+  enum f x = __builtin_elementwise_min(one, three);
+
+  _ExtInt(32) ext;
+  ext = __builtin_elementwise_min(ext, ext);
+
+  const int ci;
+  i = __builtin_elementwise_min(ci, i);
+  i = __builtin_elementwise_min(i, ci);
+  i = __builtin_elementwise_min(ci, ci);
+
+  i = __builtin_elementwise_min(i, int_as_one); // ok (attributes don't match)?
+  i = __builtin_elementwise_min(i, b);  // ok (sugar doesn't match)?
+
+  int A[10];
+  A = __builtin_elementwise_min(A, A);
+  // expected-error@-1 {{argument type 'int *' is not supported}}
+
+  int(ii);
+  int j;
+  j = __builtin_elementwise_min(i, j);
+}
Index: clang/test/CodeGen/builtins-elementwise-math.c
===
--- /dev/null
+++ clang/test/CodeGen/builtins-elementwise-math.c
@@ -0,0 +1,149 @@
+// RUN: %clang_cc1 -triple x86_64-apple-darwin %s -emit-llvm -disable-llvm-passes -o - | FileCheck %s
+
+typedef float float4 __attribute__((ext_vector_type(4)));
+typedef short int si8 __attribute__((ext_vector_type(8)));
+typedef unsigned int u4 __attribute__((ext_vector_type(4)));
+
+__attribute__((address_space(1))) int int_as_one;
+typedef int bar;
+bar b;
+
+void test_builtin_e

[PATCH] D111985: [Clang] Add elementwise min/max builtins.

2021-10-25 Thread Florian Hahn via Phabricator via cfe-commits
fhahn marked 4 inline comments as done.
fhahn added inline comments.



Comment at: clang/lib/Sema/SemaChecking.cpp:16669
+ExprResult Sema::SemaBuiltinElementwiseMath(CallExpr *TheCall,
+ExprResult CallResult) {
+  if (checkArgCount(*this, TheCall, 2))

aaron.ballman wrote:
> fhahn wrote:
> > aaron.ballman wrote:
> > > Do we actually need this parameter?
> > No, it can just return `ExprResult(TheCall)` instead I think!
> Could also return a `bool` and have the caller fiddle with `ExprResult`, too. 
> I don't have strong opinions on which way to go though.
updated to return a bool



Comment at: clang/lib/Sema/SemaChecking.cpp:16673-16678
+  Expr *A = TheCall->getArg(0);
+  Expr *B = TheCall->getArg(1);
+  QualType TyA = A->getType();
+  QualType TyB = B->getType();
+
+  if (TyA != TyB)

aaron.ballman wrote:
> fhahn wrote:
> > aaron.ballman wrote:
> > > fhahn wrote:
> > > > aaron.ballman wrote:
> > > > > Should these arguments undergo usual conversions (array to pointer 
> > > > > decay, integer promotions, etc)?
> > > > I intentionally went with not performing conversions, because it might 
> > > > lead to surprising results. If the arguments have different types, it 
> > > > is not clear to me which type should be chosen to try convert the other 
> > > > one; e.g. if we have __builtin_elementwise_max(float, int)` should the 
> > > > first argument be converted to `int` or the second one to `float`?
> > > > 
> > > > Forcing the types to match without conversion seem to make them less 
> > > > error-prone to use, but I might be missing some general rule to handle 
> > > > type conflicts here?
> > > I'm not certain how these builtins are expected to be used, but if 
> > > they're likely to be used with literals, I think we may want integer 
> > > promotions because of that alone.
> > > 
> > > Btw, given that these only have two arguments, it seems like we could use 
> > > the usual arithmetic conversions to pick a common type the same way as 
> > > happens for binary operators.
> > > 
> > > If you end up not adding any conversions here, we should have a test case 
> > > to cover passing in two array objects (which won't decay to pointers).
> > > I'm not certain how these builtins are expected to be used, but if 
> > > they're likely to be used with literals, I think we may want integer 
> > > promotions because of that alone.
> > 
> > Yes, they should ideally work with literals! I think it should be 
> > relatively straight-forward to add promotion of literals.
> > 
> > > Btw, given that these only have two arguments, it seems like we could use 
> > > the usual arithmetic conversions to pick a common type the same way as 
> > > happens for binary operators.
> > 
> > IIUC this happens in `SemaOverload.cpp`, but I am not sure how builtins 
> > would hook into the infrastructure there. Are there other builtins that are 
> > similarly overloaded by any chance?
> > Yes, they should ideally work with literals! I think it should be 
> > relatively straight-forward to add promotion of literals.
> 
> I was thinking of the literal being an `int` and the variable being a 
> `short`, so the literal isn't what needs promotion in that case. That said, I 
> suppose character literals in C++ would promote from `char` to `int`, so 
> there are some literals that could promote. That'd be a somewhat amusing test 
> case for C and C++ both (`__builtin_elementwise_max('a', 1);`).
> 
> > IUC this happens in SemaOverload.cpp, but I am not sure how builtins would 
> > hook into the infrastructure there. Are there other builtins that are 
> > similarly overloaded by any chance?
> 
> `Sema::SemaBuiltinUnorderedCompare()` uses this, for example:
> ```
>   ExprResult OrigArg0 = TheCall->getArg(0);
>   ExprResult OrigArg1 = TheCall->getArg(1);
> 
>   // Do standard promotions between the two arguments, returning their common
>   // type.
>   QualType Res = UsualArithmeticConversions(
>   OrigArg0, OrigArg1, TheCall->getExprLoc(), ACK_Comparison);
>   if (OrigArg0.isInvalid() || OrigArg1.isInvalid())
> return true;
> ```
> hat'd be a somewhat amusing test case for C and C++ both 
> (__builtin_elementwise_max('a', 1);).

I added ` i1 = __builtin_elementwise_max(1, 'a');` to the codegen tests.

> Sema::SemaBuiltinUnorderedCompare() uses this, for example:

Thanks a lot! I updated to code to use `UsualArithmeticConversions` and added 
the tests you suggested (hope I didn't miss any important ones). Looks like all 
should work as expected now.



Comment at: clang/test/Sema/builtins-elementwise-math.c:42
+  // expected-error@-1 {{argument types do not match, 'float4' (vector of 4 
'float' values) != 'int3' (vector of 3 'int' values)}}
+}

aaron.ballman wrote:
> aaron.ballman wrote:
> > fhahn wrote:
> > > aaron.ballman wrote:
> > > > Additional tests I would like to see:
> > > > ```
> > > > int i;

[PATCH] D111986: [Clang] Add elementwise abs builtin.

2021-10-26 Thread Florian Hahn via Phabricator via cfe-commits
fhahn updated this revision to Diff 382226.
fhahn marked 2 inline comments as done.
fhahn added a comment.

Rebased after recent changes in D111985 : 
changes the return type of SemaBuiltinElementwiseMathOneArg to bool and drop 
the CallResult argument. Also added tests with const, typedef'ed and variables 
with address space


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D111986/new/

https://reviews.llvm.org/D111986

Files:
  clang/include/clang/Basic/Builtins.def
  clang/include/clang/Basic/DiagnosticSemaKinds.td
  clang/include/clang/Sema/Sema.h
  clang/lib/CodeGen/CGBuiltin.cpp
  clang/lib/Sema/SemaChecking.cpp
  clang/test/CodeGen/builtins-elementwise-math.c
  clang/test/Sema/builtins-elementwise-math.c

Index: clang/test/Sema/builtins-elementwise-math.c
===
--- clang/test/Sema/builtins-elementwise-math.c
+++ clang/test/Sema/builtins-elementwise-math.c
@@ -2,6 +2,7 @@
 
 typedef float float4 __attribute__((ext_vector_type(4)));
 typedef int int3 __attribute__((ext_vector_type(3)));
+typedef unsigned unsigned4 __attribute__((ext_vector_type(4)));
 
 struct Foo {
   char *p;
@@ -11,6 +12,26 @@
 typedef int bar;
 bar b;
 
+void test_builtin_elementwise_abs(int i, double d, float4 v, int3 iv, unsigned u, unsigned4 uv) {
+  struct Foo s = __builtin_elementwise_abs(i);
+  // expected-error@-1 {{initializing 'struct Foo' with an expression of incompatible type 'int'}}
+
+  i = __builtin_elementwise_abs();
+  // expected-error@-1 {{too few arguments to function call, expected 1, have 0}}
+
+  i = __builtin_elementwise_abs(i, i);
+  // expected-error@-1 {{too many arguments to function call, expected 1, have 2}}
+
+  i = __builtin_elementwise_abs(v);
+  // expected-error@-1 {{assigning to 'int' from incompatible type 'float4' (vector of 4 'float' values)}}
+
+  u = __builtin_elementwise_abs(u);
+  // expected-error@-1 {{argument must have a signed integer or floating point type, but was an unsigned integer type}}
+
+  uv = __builtin_elementwise_abs(uv);
+  // expected-error@-1 {{argument must have a signed integer or floating point type, but was an unsigned integer type}}
+}
+
 void test_builtin_elementwise_max(int i, short s, double d, float4 v, int3 iv, int *p) {
   i = __builtin_elementwise_max(p, d);
   // expected-error@-1 {{argument types do not match, 'int *' != 'double'}}
Index: clang/test/CodeGen/builtins-elementwise-math.c
===
--- clang/test/CodeGen/builtins-elementwise-math.c
+++ clang/test/CodeGen/builtins-elementwise-math.c
@@ -8,12 +8,48 @@
 typedef int bar;
 bar b;
 
+void test_builtin_elementwise_abs(float f1, float f2, double d1, double d2,
+  float4 vf1, float4 vf2, si8 vi1, si8 vi2,
+  long long int i1, long long int i2) {
+  // CHECK-LABEL: define void @test_builtin_elementwise_abs(
+  // CHECK:  [[F1:%.+]] = load float, float* %f1.addr, align 4
+  // CHECK-NEXT:  call float @llvm.fabs.f32(float [[F1]])
+  f2 = __builtin_elementwise_abs(f1);
+
+  // CHECK:  [[D1:%.+]] = load double, double* %d1.addr, align 8
+  // CHECK-NEXT: call double @llvm.fabs.f64(double [[D1]])
+  d2 = __builtin_elementwise_abs(d1);
+
+  // CHECK:  [[VF1:%.+]] = load <4 x float>, <4 x float>* %vf1.addr, align 16
+  // CHECK-NEXT: call <4 x float> @llvm.fabs.v4f32(<4 x float> [[VF1]])
+  vf2 = __builtin_elementwise_abs(vf1);
+
+  // CHECK:  [[I1:%.+]] = load i64, i64* %i1.addr, align 8
+  // CHECK-NEXT: call i64 @llvm.abs.i64(i64 [[I1]], i1 false)
+  i2 = __builtin_elementwise_abs(i1);
+
+  // CHECK:  [[VI1:%.+]] = load <8 x i16>, <8 x i16>* %vi1.addr, align 16
+  // CHECK-NEXT: call <8 x i16> @llvm.abs.v8i16(<8 x i16> [[VI1]], i1 false)
+  vi2 = __builtin_elementwise_abs(vi1);
+
+  // CHECK:  [[CVI2:%.+]] = load <8 x i16>, <8 x i16>* %cvi2, align 16
+  // CHECK-NEXT: call <8 x i16> @llvm.abs.v8i16(<8 x i16> [[CVI2]], i1 false)
+  const si8 cvi2 = vi2;
+  vi2 = __builtin_elementwise_abs(cvi2);
+
+  // CHECK:  [[IA1:%.+]] = load i32, i32 addrspace(1)* @int_as_one, align 4
+  // CHECK-NEXT: call i32 @llvm.abs.i32(i32 [[IA1]], i1 false)
+  b = __builtin_elementwise_abs(int_as_one);
+
+  // CHECK:   call i32 @llvm.abs.i32(i32 -10, i1 false)
+  b = __builtin_elementwise_abs(-10);
+}
+
 void test_builtin_elementwise_max(float f1, float f2, double d1, double d2,
   float4 vf1, float4 vf2, long long int i1,
   long long int i2, si8 vi1, si8 vi2,
   unsigned u1, unsigned u2, u4 vu1, u4 vu2) {
   // CHECK-LABEL: define void @test_builtin_elementwise_max(
-
   // CHECK:  [[F1:%.+]] = load float, float* %f1.addr, align 4
   // CHECK-NEXT: [[F2:%.+]] = load float, float* %f2.addr, align 4
   // CHECK-NEXT:  call float @llvm.maxnum.f32(fl

[PATCH] D112001: [Clang] Add min/max reduction builtins.

2021-10-26 Thread Florian Hahn via Phabricator via cfe-commits
fhahn updated this revision to Diff 382240.
fhahn added a comment.

Rebased after recent changes in D111985  
https://reviews.llvm.org/D111985: changes the return type of 
SemaBuiltinReduceMath to bool and drop the CallResult argument.

Also added tests with const and variables with address space and moved tests to 
builtins-reduction-math.c instead of builtins-elementwise-math.c


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D112001/new/

https://reviews.llvm.org/D112001

Files:
  clang/include/clang/Basic/Builtins.def
  clang/include/clang/Sema/Sema.h
  clang/lib/CodeGen/CGBuiltin.cpp
  clang/lib/Sema/SemaChecking.cpp
  clang/test/CodeGen/builtins-reduction-math.c
  clang/test/Sema/builtins-reduction-math.c

Index: clang/test/Sema/builtins-reduction-math.c
===
--- /dev/null
+++ clang/test/Sema/builtins-reduction-math.c
@@ -0,0 +1,37 @@
+// RUN: %clang_cc1 %s -pedantic -verify -triple=x86_64-apple-darwin9
+
+typedef float float4 __attribute__((ext_vector_type(4)));
+typedef int int3 __attribute__((ext_vector_type(3)));
+typedef unsigned unsigned4 __attribute__((ext_vector_type(4)));
+
+struct Foo {
+  char *p;
+};
+
+void test_builtin_reduce_max(int i, float4 v, int3 iv) {
+  struct Foo s = __builtin_reduce_max(iv);
+  // expected-error@-1 {{initializing 'struct Foo' with an expression of incompatible type 'int'}}
+
+  i = __builtin_reduce_max(v, v);
+  // expected-error@-1 {{too many arguments to function call, expected 1, have 2}}
+
+  i = __builtin_reduce_max();
+  // expected-error@-1 {{too few arguments to function call, expected 1, have 0}}
+
+  i = __builtin_reduce_max(i);
+  // expected-error@-1 {{argument must have a vector type, but was 'int'}}
+}
+
+void test_builtin_reduce_min(int i, float4 v, int3 iv) {
+  struct Foo s = __builtin_reduce_min(iv);
+  // expected-error@-1 {{initializing 'struct Foo' with an expression of incompatible type 'int'}}
+
+  i = __builtin_reduce_min(v, v);
+  // expected-error@-1 {{too many arguments to function call, expected 1, have 2}}
+
+  i = __builtin_reduce_min();
+  // expected-error@-1 {{too few arguments to function call, expected 1, have 0}}
+
+  i = __builtin_reduce_min(i);
+  // expected-error@-1 {{argument must have a vector type, but was 'int'}}
+}
Index: clang/test/CodeGen/builtins-reduction-math.c
===
--- /dev/null
+++ clang/test/CodeGen/builtins-reduction-math.c
@@ -0,0 +1,59 @@
+// RUN: %clang_cc1 -triple x86_64-apple-darwin %s -emit-llvm -disable-llvm-passes -o - | FileCheck %s
+
+typedef float float4 __attribute__((ext_vector_type(4)));
+typedef short int si8 __attribute__((ext_vector_type(8)));
+typedef unsigned int u4 __attribute__((ext_vector_type(4)));
+
+__attribute__((address_space(1))) float4 vf1_as_one;
+
+void test_builtin_reduce_max(float4 vf1, si8 vi1, u4 vu1) {
+  // CHECK-LABEL: define void @test_builtin_reduce_max(
+  // CHECK:  [[VF1:%.+]] = load <4 x float>, <4 x float>* %vf1.addr, align 16
+  // CHECK-NEXT: call float @llvm.vector.reduce.fmax.v4f32(<4 x float> [[VF1]])
+  float r1 = __builtin_reduce_max(vf1);
+
+  // CHECK:  [[VI1:%.+]] = load <8 x i16>, <8 x i16>* %vi1.addr, align 16
+  // CHECK-NEXT: call i16 @llvm.vector.reduce.smax.v8i16(<8 x i16> [[VI1]])
+  short r2 = __builtin_reduce_max(vi1);
+
+  // CHECK:  [[VU1:%.+]] = load <4 x i32>, <4 x i32>* %vu1.addr, align 16
+  // CHECK-NEXT: call i32 @llvm.vector.reduce.umax.v4i32(<4 x i32> [[VU1]])
+  unsigned r3 = __builtin_reduce_max(vu1);
+
+  // CHECK:  [[VF1_AS1:%.+]] = load <4 x float>, <4 x float> addrspace(1)* @vf1_as_one, align 16
+  // CHECK-NEXT: [[RDX1:%.+]] = call float @llvm.vector.reduce.fmax.v4f32(<4 x float> [[VF1_AS1]])
+  // CHECK-NEXT: fpext float [[RDX1]] to double
+  const double r4 = __builtin_reduce_max(vf1_as_one);
+
+  // CHECK:  [[CVI1:%.+]] = load <8 x i16>, <8 x i16>* %cvi1, align 16
+  // CHECK-NEXT: [[RDX2:%.+]] = call i16 @llvm.vector.reduce.smax.v8i16(<8 x i16> [[CVI1]])
+  // CHECK-NEXT: sext i16 [[RDX2]] to i64
+  const si8 cvi1 = vi1;
+  unsigned long long r5 = __builtin_reduce_max(cvi1);
+}
+
+void test_builtin_reduce_min(float4 vf1, si8 vi1, u4 vu1) {
+  // CHECK-LABEL: define void @test_builtin_reduce_min(
+  // CHECK:  [[VF1:%.+]] = load <4 x float>, <4 x float>* %vf1.addr, align 16
+  // CHECK-NEXT: call float @llvm.vector.reduce.fmin.v4f32(<4 x float> [[VF1]])
+  float r1 = __builtin_reduce_min(vf1);
+
+  // CHECK:  [[VI1:%.+]] = load <8 x i16>, <8 x i16>* %vi1.addr, align 16
+  // CHECK-NEXT: call i16 @llvm.vector.reduce.smin.v8i16(<8 x i16> [[VI1]])
+  short r2 = __builtin_reduce_min(vi1);
+
+  // CHECK:  [[VU1:%.+]] = load <4 x i32>, <4 x i32>* %vu1.addr, align 16
+  // CHECK-NEXT: call i32 @llvm.vector.reduce.umin.v4i32(<4 x i32> [[VU1]])
+  unsigned r3 = __builtin_reduce_min(vu1);
+
+  // CHECK:

[PATCH] D112532: [Matrix] Replace some err kinds with err_builtin_invalid_arg_type. (NFC)

2021-10-26 Thread Florian Hahn via Phabricator via cfe-commits
fhahn created this revision.
fhahn added reviewers: aaron.ballman, erichkeane, rjmccall.
Herald added a subscriber: tschuett.
fhahn requested review of this revision.
Herald added a project: clang.

Replace some custom matrix diagnostic kinds with the more generic
err_builtin_invalid_arg_type introduced in D111985 
.


Repository:
  rG LLVM Github Monorepo

https://reviews.llvm.org/D112532

Files:
  clang/include/clang/Basic/DiagnosticSemaKinds.td
  clang/lib/Sema/SemaChecking.cpp


Index: clang/lib/Sema/SemaChecking.cpp
===
--- clang/lib/Sema/SemaChecking.cpp
+++ clang/lib/Sema/SemaChecking.cpp
@@ -16578,7 +16578,8 @@
 
   auto *MType = Matrix->getType()->getAs();
   if (!MType) {
-Diag(Matrix->getBeginLoc(), diag::err_builtin_matrix_arg);
+Diag(Matrix->getBeginLoc(), diag::err_builtin_invalid_arg_type)
+<< 1 << "matrix" << Matrix->getType();
 return ExprError();
   }
 
@@ -16649,15 +16650,17 @@
   auto *PtrTy = PtrExpr->getType()->getAs();
   QualType ElementTy;
   if (!PtrTy) {
-Diag(PtrExpr->getBeginLoc(), diag::err_builtin_matrix_pointer_arg)
-<< PtrArgIdx + 1;
+Diag(PtrExpr->getBeginLoc(), diag::err_builtin_invalid_arg_type)
+<< PtrArgIdx + 1 << "pointer to a valid matrix element type"
+<< PtrExpr->getType();
 ArgError = true;
   } else {
 ElementTy = PtrTy->getPointeeType().getUnqualifiedType();
 
 if (!ConstantMatrixType::isValidElementType(ElementTy)) {
-  Diag(PtrExpr->getBeginLoc(), diag::err_builtin_matrix_pointer_arg)
-  << PtrArgIdx + 1;
+  Diag(PtrExpr->getBeginLoc(), diag::err_builtin_invalid_arg_type)
+  << PtrArgIdx + 1 << "pointer to a valid matrix element type"
+  << PtrExpr->getType();
   ArgError = true;
 }
   }
@@ -16756,7 +16759,8 @@
 
   auto *MatrixTy = MatrixExpr->getType()->getAs();
   if (!MatrixTy) {
-Diag(MatrixExpr->getBeginLoc(), diag::err_builtin_matrix_arg) << 0;
+Diag(MatrixExpr->getBeginLoc(), diag::err_builtin_invalid_arg_type)
+<< 1 << "matrix" << MatrixExpr->getType();
 ArgError = true;
   }
 
@@ -16775,8 +16779,9 @@
   // Check pointer argument.
   auto *PtrTy = PtrExpr->getType()->getAs();
   if (!PtrTy) {
-Diag(PtrExpr->getBeginLoc(), diag::err_builtin_matrix_pointer_arg)
-<< PtrArgIdx + 1;
+Diag(PtrExpr->getBeginLoc(), diag::err_builtin_invalid_arg_type)
+<< PtrArgIdx + 1 << "pointer to a valid matrix element type"
+<< PtrExpr->getType();
 ArgError = true;
   } else {
 QualType ElementTy = PtrTy->getPointeeType();
Index: clang/include/clang/Basic/DiagnosticSemaKinds.td
===
--- clang/include/clang/Basic/DiagnosticSemaKinds.td
+++ clang/include/clang/Basic/DiagnosticSemaKinds.td
@@ -11318,11 +11318,8 @@
   "matrix row and column subscripts cannot be separated by any expression">;
 def err_matrix_subscript_comma: Error<
   "comma expressions are not allowed as indices in matrix subscript 
expressions">;
-def err_builtin_matrix_arg: Error<"1st argument must be a matrix">;
 def err_builtin_matrix_scalar_unsigned_arg: Error<
   "%0 argument must be a constant unsigned integer expression">;
-def err_builtin_matrix_pointer_arg: Error<
-  "%ordinal0 argument must be a pointer to a valid matrix element type">;
 def err_builtin_matrix_pointer_arg_mismatch: Error<
   "the pointee of the 2nd argument must match the element type of the 1st 
argument (%0 != %1)">;
 def err_builtin_matrix_store_to_const: Error<


Index: clang/lib/Sema/SemaChecking.cpp
===
--- clang/lib/Sema/SemaChecking.cpp
+++ clang/lib/Sema/SemaChecking.cpp
@@ -16578,7 +16578,8 @@
 
   auto *MType = Matrix->getType()->getAs();
   if (!MType) {
-Diag(Matrix->getBeginLoc(), diag::err_builtin_matrix_arg);
+Diag(Matrix->getBeginLoc(), diag::err_builtin_invalid_arg_type)
+<< 1 << "matrix" << Matrix->getType();
 return ExprError();
   }
 
@@ -16649,15 +16650,17 @@
   auto *PtrTy = PtrExpr->getType()->getAs();
   QualType ElementTy;
   if (!PtrTy) {
-Diag(PtrExpr->getBeginLoc(), diag::err_builtin_matrix_pointer_arg)
-<< PtrArgIdx + 1;
+Diag(PtrExpr->getBeginLoc(), diag::err_builtin_invalid_arg_type)
+<< PtrArgIdx + 1 << "pointer to a valid matrix element type"
+<< PtrExpr->getType();
 ArgError = true;
   } else {
 ElementTy = PtrTy->getPointeeType().getUnqualifiedType();
 
 if (!ConstantMatrixType::isValidElementType(ElementTy)) {
-  Diag(PtrExpr->getBeginLoc(), diag::err_builtin_matrix_pointer_arg)
-  << PtrArgIdx + 1;
+  Diag(PtrExpr->getBeginLoc(), diag::err_builtin_invalid_arg_type)
+  << PtrArgIdx + 1 << "pointer to a valid matrix element type"
+  << PtrExpr->getType();
   ArgError = true;
 }
   }
@@ -16756,7 +16759,8 @@
 
   a

[PATCH] D111985: [Clang] Add elementwise min/max builtins.

2021-10-26 Thread Florian Hahn via Phabricator via cfe-commits
fhahn updated this revision to Diff 382300.
fhahn marked 3 inline comments as done.
fhahn added a comment.

Address latest comments, thanks

- Added a generic `err_builtin_invalid_arg_type` diagnostic kind, which can 
also be used for some of the matrix type mismatches (see D112532 
).
- Dropped `err_elementwise_math_arg_types_mismatch` in favor of the existing 
`err_typecheck_call_different_arg_types`.
- Use `Res` to set the call type
- Add tests with _Complex, which gets rejected.
- add C++ test that check constness of builtins.



In D111985#3087057 , @aaron.ballman 
wrote:

> I thought of another test case -- should these new functions work on complex 
> types? (Those are weird enough we may want to consider adding both Sema and 
> CodeGen tests if we do support them, and Sema tests alone if we don't.)

At the moment they should not work with complex types (like C99's _Complex). 
The problem there is that there is no dedicated IR type and the LLVM intrinsics 
do not support complex types. So at the moment we cannot lower such operations 
effectively.

I think it would make sense to extend them to complex types once we can better 
model those operations in LLVM IR.


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D111985/new/

https://reviews.llvm.org/D111985

Files:
  clang/include/clang/Basic/Builtins.def
  clang/include/clang/Basic/DiagnosticSemaKinds.td
  clang/include/clang/Sema/Sema.h
  clang/lib/CodeGen/CGBuiltin.cpp
  clang/lib/Sema/SemaChecking.cpp
  clang/test/CodeGen/builtins-elementwise-math.c
  clang/test/Sema/builtins-elementwise-math.c
  clang/test/SemaCXX/builtins-elementwise-math.cpp

Index: clang/test/SemaCXX/builtins-elementwise-math.cpp
===
--- /dev/null
+++ clang/test/SemaCXX/builtins-elementwise-math.cpp
@@ -0,0 +1,31 @@
+// RUN: %clang_cc1 %s -std=c++17 -pedantic -verify -triple=x86_64-apple-darwin9
+
+// Simple is_const implementation.
+struct true_type {
+  static const bool value = true;
+};
+
+struct false_type {
+  static const bool value = false;
+};
+
+template  struct is_const : false_type {};
+template  struct is_const : true_type {};
+
+// expected-no-diagnostics
+
+void test_builtin_elementwise_max() {
+  const int a = 2;
+  int b = 1;
+  static_assert(!is_const::value);
+  static_assert(!is_const::value);
+  static_assert(!is_const::value);
+}
+
+void test_builtin_elementwise_min() {
+  const int a = 2;
+  int b = 1;
+  static_assert(!is_const::value);
+  static_assert(!is_const::value);
+  static_assert(!is_const::value);
+}
Index: clang/test/Sema/builtins-elementwise-math.c
===
--- /dev/null
+++ clang/test/Sema/builtins-elementwise-math.c
@@ -0,0 +1,116 @@
+// RUN: %clang_cc1 -std=c99 %s -pedantic -verify -triple=x86_64-apple-darwin9
+
+typedef float float4 __attribute__((ext_vector_type(4)));
+typedef int int3 __attribute__((ext_vector_type(3)));
+
+struct Foo {
+  char *p;
+};
+
+__attribute__((address_space(1))) int int_as_one;
+typedef int bar;
+bar b;
+
+void test_builtin_elementwise_max(int i, short s, double d, float4 v, int3 iv, int *p) {
+  i = __builtin_elementwise_max(p, d);
+  // expected-error@-1 {{arguments are of different types ('int *' vs 'double')}}
+
+  struct Foo foo = __builtin_elementwise_max(i, i);
+  // expected-error@-1 {{initializing 'struct Foo' with an expression of incompatible type 'int'}}
+
+  i = __builtin_elementwise_max(i);
+  // expected-error@-1 {{too few arguments to function call, expected 2, have 1}}
+
+  i = __builtin_elementwise_max();
+  // expected-error@-1 {{too few arguments to function call, expected 2, have 0}}
+
+  i = __builtin_elementwise_max(i, i, i);
+  // expected-error@-1 {{too many arguments to function call, expected 2, have 3}}
+
+  i = __builtin_elementwise_max(v, iv);
+  // expected-error@-1 {{arguments are of different types ('float4' (vector of 4 'float' values) vs 'int3' (vector of 3 'int' values))}}
+
+  s = __builtin_elementwise_max(i, s);
+
+  enum e { one,
+   two };
+  i = __builtin_elementwise_max(one, two);
+
+  enum f { three };
+  enum f x = __builtin_elementwise_max(one, three);
+
+  _ExtInt(32) ext;
+  ext = __builtin_elementwise_max(ext, ext);
+
+  const int ci;
+  i = __builtin_elementwise_max(ci, i);
+  i = __builtin_elementwise_max(i, ci);
+  i = __builtin_elementwise_max(ci, ci);
+
+  i = __builtin_elementwise_max(i, int_as_one); // ok (attributes don't match)?
+  i = __builtin_elementwise_max(i, b);  // ok (sugar doesn't match)?
+
+  int A[10];
+  A = __builtin_elementwise_max(A, A);
+  // expected-error@-1 {{1st argument must be a vector, integer or floating point type (was 'int *')}}
+
+  int(ii);
+  int j;
+  j = __builtin_elementwise_max(i, j);
+
+  _Complex float c1, c2;
+  c1 = __builtin_elementwise_max(c1, c2);
+  // expec

[PATCH] D111985: [Clang] Add elementwise min/max builtins.

2021-10-26 Thread Florian Hahn via Phabricator via cfe-commits
fhahn marked 3 inline comments as done.
fhahn added inline comments.



Comment at: clang/include/clang/Basic/DiagnosticSemaKinds.td:8747-8748
 
+def err_elementwise_math_arg_types_mismatch : Error <
+  "argument types do not match, %0 != %1">;
+

aaron.ballman wrote:
> Does `err_typecheck_call_different_arg_types` suffice?
 `err_typecheck_call_different_arg_types` is sufficient, thanks!



Comment at: clang/include/clang/Basic/DiagnosticSemaKinds.td:8750-8751
+
+def err_elementwise_math_invalid_arg_type: Error <
+  "argument type %0 is not supported">;
+

aaron.ballman wrote:
> It'd be nice to avoid this entirely as the diagnostic situation is one we 
> would have elsewhere (so we should be able to use common diagnostic checking 
> code from here and places like `SemaBuiltinMatrixColumnMajorLoad()` ideally).
I turned the diagnostic kind into a more generic one and also put up a patch to 
use them instead some of the custom matrix diagnostic kinds (D112532). WDYT?

I'm not sure if there's much potential for sharing the checking code, as it 
looks like most places check for slightly different things (or the check is 
quite compact already).



Comment at: clang/lib/Sema/SemaChecking.cpp:16662-16667
+  if (!Ty->getAs() && !ConstantMatrixType::isValidElementType(Ty)) 
{
+S.Diag(Loc, diag::err_elementwise_math_invalid_arg_type) << Ty;
+return true;
+  }
+  return false;
+}

aaron.ballman wrote:
> Related to the comment above on the diagnostic, I'm wondering if we want to 
> abstract this into a helper function that gets used by all the elementwise 
> builtins you're adding?
Unfortunately I am not sure which code this is referring to. The element type 
check is already a generic function to be used to check the new builtins with 1 
arg and the reduction builtins. 



Comment at: clang/lib/Sema/SemaChecking.cpp:16695
+  TheCall->setArg(1, B.get());
+  TheCall->setType(TyB);
+  return false;

aaron.ballman wrote:
> I think you want to set this to `Res`, because that's the common type between 
> `TyB` and `TyA`, right? That will also ensure that qualifiers are stripped, I 
> believe. e.g.,
> ```
> const int a = 2;
> int b = 1;
> static_assert(!std::is_const_v);
> static_assert(!std::is_const_v);
> ```
Agreed, using `TyB` is confusing, so I updated it. I *think* it was still doing 
the right thing, because `TyB` is to `B`'s type after conversion, so I *think* 
that would be to common type already. 

I also added a `.cpp` Sema test file to check the constness.


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D111985/new/

https://reviews.llvm.org/D111985

___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D111529: Specify Clang vector builtins.

2021-10-26 Thread Florian Hahn via Phabricator via cfe-commits
This revision was automatically updated to reflect the committed changes.
Closed by commit rG025988ded6b2: Specify Clang vector builtins. (authored by 
fhahn).

Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D111529/new/

https://reviews.llvm.org/D111529

Files:
  clang/docs/LanguageExtensions.rst


Index: clang/docs/LanguageExtensions.rst
===
--- clang/docs/LanguageExtensions.rst
+++ clang/docs/LanguageExtensions.rst
@@ -506,6 +506,83 @@
   If it's an extension (OpenCL) vector, it's only available in C and OpenCL C.
   And it selects base on signedness of the condition operands (OpenCL v1.1 
s6.3.9).
 
+Vector Builtins
+---
+
+**Note: The implementation of vector builtins is work-in-progress and 
incomplete.**
+
+In addition to the operators mentioned above, Clang provides a set of builtins
+to perform additional operations on certain scalar and vector types.
+
+Let ``T`` be one of the following types:
+
+* an integer type (as in C2x 6.2.5p19), but excluding enumerated types and 
_Bool
+* the standard floating types float or double
+* a half-precision floating point type, if one is supported on the target
+* a vector type.
+
+For scalar types, consider the operation applied to a vector with a single 
element.
+
+*Elementwise Builtins*
+
+Each builtin returns a vector equivalent to applying the specified operation
+elementwise to the input.
+
+Unless specified otherwise operation(±0) = ±0 and operation(±infinity) = 
±infinity
+
+= 
 
=
+ Name  Operation   
 Supported element types
+= 
 
=
+ T __builtin_elementwise_abs(T x)  return the absolute value of a 
number x; the absolute value of   signed integer and floating point types
+   the most negative integer remains 
the most negative integer
+ T __builtin_elementwise_ceil(T x) return the smallest integral value 
greater than or equal to xfloating point types
+ T __builtin_elementwise_floor(T x)return the largest integral value 
less than or equal to xfloating point types
+ T __builtin_elementwise_roundeven(T x)round x to the nearest integer 
value in floating point format,   floating point types
+   rounding halfway cases to even 
(that is, to the nearest value
+   that is an even integer), 
regardless of the current rounding
+   direction.
+ T__builtin_elementwise_trunc(T x) return the integral value nearest 
to but no larger infloating point types
+   magnitude than x
+ T __builtin_elementwise_max(T x, T y) return x or y, whichever is larger  
 integer and floating point types
+ T __builtin_elementwise_min(T x, T y) return x or y, whichever is smaller 
 integer and floating point types
+= 
 
=
+
+
+*Reduction Builtins*
+
+Each builtin returns a scalar equivalent to applying the specified
+operation(x, y) as recursive even-odd pairwise reduction to all vector
+elements. ``operation(x, y)`` is repeatedly applied to each non-overlapping
+even-odd element pair with indices ``i * 2`` and ``i * 2 + 1`` with
+``i in [0, Number of elements / 2)``. If the numbers of elements is not a
+power of 2, the vector is widened with neutral elements for the reduction
+at the end to the next power of 2.
+
+Example:
+
+.. code-block:: c++
+
+__builtin_reduce_add([e3, e2, e1, e0]) = __builtin_reduced_add([e3 + e2, 
e1 + e0])
+   = (e3 + e2) + (e1 + e0)
+
+
+Let ``VT`` be a vector type and ``ET`` the element type of ``VT``.
+
+=== 
 
==
+ NameOperation 
   Supported element types
+=== 
 
==
+ ET __builtin_reduce_max(VT a)   return x or y, whichever is larger; 
If exactly one argument is   integer and floating point types
+ a NaN, return the other argument. If 
both arguments are NaNs,
+ 

[PATCH] D111985: [Clang] Add elementwise min/max builtins.

2021-10-26 Thread Florian Hahn via Phabricator via cfe-commits
This revision was automatically updated to reflect the committed changes.
fhahn marked 3 inline comments as done.
Closed by commit rG1ef25d28c19e: [Clang] Add elementwise min/max builtins. 
(authored by fhahn).

Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D111985/new/

https://reviews.llvm.org/D111985

Files:
  clang/include/clang/Basic/Builtins.def
  clang/include/clang/Basic/DiagnosticSemaKinds.td
  clang/include/clang/Sema/Sema.h
  clang/lib/CodeGen/CGBuiltin.cpp
  clang/lib/Sema/SemaChecking.cpp
  clang/test/CodeGen/builtins-elementwise-math.c
  clang/test/Sema/builtins-elementwise-math.c
  clang/test/SemaCXX/builtins-elementwise-math.cpp

Index: clang/test/SemaCXX/builtins-elementwise-math.cpp
===
--- /dev/null
+++ clang/test/SemaCXX/builtins-elementwise-math.cpp
@@ -0,0 +1,31 @@
+// RUN: %clang_cc1 %s -std=c++17 -pedantic -verify -triple=x86_64-apple-darwin9
+
+// Simple is_const implementation.
+struct true_type {
+  static const bool value = true;
+};
+
+struct false_type {
+  static const bool value = false;
+};
+
+template  struct is_const : false_type {};
+template  struct is_const : true_type {};
+
+// expected-no-diagnostics
+
+void test_builtin_elementwise_max() {
+  const int a = 2;
+  int b = 1;
+  static_assert(!is_const::value);
+  static_assert(!is_const::value);
+  static_assert(!is_const::value);
+}
+
+void test_builtin_elementwise_min() {
+  const int a = 2;
+  int b = 1;
+  static_assert(!is_const::value);
+  static_assert(!is_const::value);
+  static_assert(!is_const::value);
+}
Index: clang/test/Sema/builtins-elementwise-math.c
===
--- /dev/null
+++ clang/test/Sema/builtins-elementwise-math.c
@@ -0,0 +1,116 @@
+// RUN: %clang_cc1 -std=c99 %s -pedantic -verify -triple=x86_64-apple-darwin9
+
+typedef float float4 __attribute__((ext_vector_type(4)));
+typedef int int3 __attribute__((ext_vector_type(3)));
+
+struct Foo {
+  char *p;
+};
+
+__attribute__((address_space(1))) int int_as_one;
+typedef int bar;
+bar b;
+
+void test_builtin_elementwise_max(int i, short s, double d, float4 v, int3 iv, int *p) {
+  i = __builtin_elementwise_max(p, d);
+  // expected-error@-1 {{arguments are of different types ('int *' vs 'double')}}
+
+  struct Foo foo = __builtin_elementwise_max(i, i);
+  // expected-error@-1 {{initializing 'struct Foo' with an expression of incompatible type 'int'}}
+
+  i = __builtin_elementwise_max(i);
+  // expected-error@-1 {{too few arguments to function call, expected 2, have 1}}
+
+  i = __builtin_elementwise_max();
+  // expected-error@-1 {{too few arguments to function call, expected 2, have 0}}
+
+  i = __builtin_elementwise_max(i, i, i);
+  // expected-error@-1 {{too many arguments to function call, expected 2, have 3}}
+
+  i = __builtin_elementwise_max(v, iv);
+  // expected-error@-1 {{arguments are of different types ('float4' (vector of 4 'float' values) vs 'int3' (vector of 3 'int' values))}}
+
+  s = __builtin_elementwise_max(i, s);
+
+  enum e { one,
+   two };
+  i = __builtin_elementwise_max(one, two);
+
+  enum f { three };
+  enum f x = __builtin_elementwise_max(one, three);
+
+  _ExtInt(32) ext;
+  ext = __builtin_elementwise_max(ext, ext);
+
+  const int ci;
+  i = __builtin_elementwise_max(ci, i);
+  i = __builtin_elementwise_max(i, ci);
+  i = __builtin_elementwise_max(ci, ci);
+
+  i = __builtin_elementwise_max(i, int_as_one); // ok (attributes don't match)?
+  i = __builtin_elementwise_max(i, b);  // ok (sugar doesn't match)?
+
+  int A[10];
+  A = __builtin_elementwise_max(A, A);
+  // expected-error@-1 {{1st argument must be a vector, integer or floating point type (was 'int *')}}
+
+  int(ii);
+  int j;
+  j = __builtin_elementwise_max(i, j);
+
+  _Complex float c1, c2;
+  c1 = __builtin_elementwise_max(c1, c2);
+  // expected-error@-1 {{1st argument must be a vector, integer or floating point type (was '_Complex float')}}
+}
+
+void test_builtin_elementwise_min(int i, short s, double d, float4 v, int3 iv, int *p) {
+  i = __builtin_elementwise_min(p, d);
+  // expected-error@-1 {{arguments are of different types ('int *' vs 'double')}}
+
+  struct Foo foo = __builtin_elementwise_min(i, i);
+  // expected-error@-1 {{initializing 'struct Foo' with an expression of incompatible type 'int'}}
+
+  i = __builtin_elementwise_min(i);
+  // expected-error@-1 {{too few arguments to function call, expected 2, have 1}}
+
+  i = __builtin_elementwise_min();
+  // expected-error@-1 {{too few arguments to function call, expected 2, have 0}}
+
+  i = __builtin_elementwise_min(i, i, i);
+  // expected-error@-1 {{too many arguments to function call, expected 2, have 3}}
+
+  i = __builtin_elementwise_min(v, iv);
+  // expected-error@-1 {{arguments are of different types ('float4' (vector of 4 'float' values) vs 'int3' (vector of 3 'int' values))}}
+
+  s = __builtin_elemen

[PATCH] D112532: [Matrix] Replace some err kinds with err_builtin_invalid_arg_type. (NFC)

2021-10-26 Thread Florian Hahn via Phabricator via cfe-commits
fhahn updated this revision to Diff 382373.
fhahn marked an inline comment as done.
fhahn added a comment.

Reabsed after landing D111985 . Also turned 
the custom message parts into a select as suggested.

In D112532#3087371 , @aaron.ballman 
wrote:

> In general, I like the direction of this cleanup. Thanks!
>
> In D112532#3087293 , @erichkeane 
> wrote:
>
>> I'm fine with this change in general... but did this not manage to break any 
>> tests?
>
> Precommit CI says things are broken: 
> https://buildkite.com/llvm-project/premerge-checks/builds/62247#63e5ea73-b0b3-4df4-898a-dd05d1f4bf81

I think that is a build failure due the me not linking the dependency in Phab. 
Now that  D111985  has landed it should be 
come back green.


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D112532/new/

https://reviews.llvm.org/D112532

Files:
  clang/include/clang/Basic/DiagnosticSemaKinds.td
  clang/lib/Sema/SemaChecking.cpp


Index: clang/lib/Sema/SemaChecking.cpp
===
--- clang/lib/Sema/SemaChecking.cpp
+++ clang/lib/Sema/SemaChecking.cpp
@@ -16530,7 +16530,7 @@
 QualType Ty) {
   if (!Ty->getAs() && !ConstantMatrixType::isValidElementType(Ty)) 
{
 S.Diag(Loc, diag::err_builtin_invalid_arg_type)
-<< 1 << "vector, integer or floating point type" << Ty;
+<< 1 << 0 << Ty;
 return true;
   }
   return false;
@@ -16578,7 +16578,8 @@
 
   auto *MType = Matrix->getType()->getAs();
   if (!MType) {
-Diag(Matrix->getBeginLoc(), diag::err_builtin_matrix_arg);
+Diag(Matrix->getBeginLoc(), diag::err_builtin_invalid_arg_type)
+<< 1 << 1 << Matrix->getType();
 return ExprError();
   }
 
@@ -16649,15 +16650,17 @@
   auto *PtrTy = PtrExpr->getType()->getAs();
   QualType ElementTy;
   if (!PtrTy) {
-Diag(PtrExpr->getBeginLoc(), diag::err_builtin_matrix_pointer_arg)
-<< PtrArgIdx + 1;
+Diag(PtrExpr->getBeginLoc(), diag::err_builtin_invalid_arg_type)
+<< PtrArgIdx + 1 << 2
+<< PtrExpr->getType();
 ArgError = true;
   } else {
 ElementTy = PtrTy->getPointeeType().getUnqualifiedType();
 
 if (!ConstantMatrixType::isValidElementType(ElementTy)) {
-  Diag(PtrExpr->getBeginLoc(), diag::err_builtin_matrix_pointer_arg)
-  << PtrArgIdx + 1;
+  Diag(PtrExpr->getBeginLoc(), diag::err_builtin_invalid_arg_type)
+  << PtrArgIdx + 1 << 2
+  << PtrExpr->getType();
   ArgError = true;
 }
   }
@@ -16756,7 +16759,8 @@
 
   auto *MatrixTy = MatrixExpr->getType()->getAs();
   if (!MatrixTy) {
-Diag(MatrixExpr->getBeginLoc(), diag::err_builtin_matrix_arg) << 0;
+Diag(MatrixExpr->getBeginLoc(), diag::err_builtin_invalid_arg_type)
+<< 1 << 1 << MatrixExpr->getType();
 ArgError = true;
   }
 
@@ -16775,8 +16779,9 @@
   // Check pointer argument.
   auto *PtrTy = PtrExpr->getType()->getAs();
   if (!PtrTy) {
-Diag(PtrExpr->getBeginLoc(), diag::err_builtin_matrix_pointer_arg)
-<< PtrArgIdx + 1;
+Diag(PtrExpr->getBeginLoc(), diag::err_builtin_invalid_arg_type)
+<< PtrArgIdx + 1 << 2
+<< PtrExpr->getType();
 ArgError = true;
   } else {
 QualType ElementTy = PtrTy->getPointeeType();
Index: clang/include/clang/Basic/DiagnosticSemaKinds.td
===
--- clang/include/clang/Basic/DiagnosticSemaKinds.td
+++ clang/include/clang/Basic/DiagnosticSemaKinds.td
@@ -11304,7 +11304,9 @@
   "'__builtin_launder' is not allowed">;
 
 def err_builtin_invalid_arg_type: Error <
-  "%ordinal0 argument must be a %1 (was %2)">;
+  "%ordinal0 argument must be a "
+  "%select{vector, integer or floating point type|matrix|"
+   "pointer to a valid matrix element type}1 (was %2)">;
 
 def err_builtin_matrix_disabled: Error<
   "matrix types extension is disabled. Pass -fenable-matrix to enable it">;
@@ -11318,11 +11320,8 @@
   "matrix row and column subscripts cannot be separated by any expression">;
 def err_matrix_subscript_comma: Error<
   "comma expressions are not allowed as indices in matrix subscript 
expressions">;
-def err_builtin_matrix_arg: Error<"1st argument must be a matrix">;
 def err_builtin_matrix_scalar_unsigned_arg: Error<
   "%0 argument must be a constant unsigned integer expression">;
-def err_builtin_matrix_pointer_arg: Error<
-  "%ordinal0 argument must be a pointer to a valid matrix element type">;
 def err_builtin_matrix_pointer_arg_mismatch: Error<
   "the pointee of the 2nd argument must match the element type of the 1st 
argument (%0 != %1)">;
 def err_builtin_matrix_store_to_const: Error<


Index: clang/lib/Sema/SemaChecking.cpp
===
--- clang/lib/Sema/SemaC

[PATCH] D112532: [Matrix] Replace some err kinds with err_builtin_invalid_arg_type. (NFC)

2021-10-26 Thread Florian Hahn via Phabricator via cfe-commits
fhahn added inline comments.



Comment at: clang/lib/Sema/SemaChecking.cpp:16654
+Diag(PtrExpr->getBeginLoc(), diag::err_builtin_invalid_arg_type)
+<< PtrArgIdx + 1 << "pointer to a valid matrix element type"
+<< PtrExpr->getType();

erichkeane wrote:
> Can you make these be a "select" instead?  It makes it really difficult to 
> localize if we do this.
done, thanks!


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D112532/new/

https://reviews.llvm.org/D112532

___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D111986: [Clang] Add elementwise abs builtin.

2021-10-26 Thread Florian Hahn via Phabricator via cfe-commits
fhahn updated this revision to Diff 382376.
fhahn marked 2 inline comments as done.
fhahn added a comment.

Rebased and updated to use `err_builtin_invalid_arg_type`.


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D111986/new/

https://reviews.llvm.org/D111986

Files:
  clang/include/clang/Basic/Builtins.def
  clang/include/clang/Basic/DiagnosticSemaKinds.td
  clang/include/clang/Sema/Sema.h
  clang/lib/CodeGen/CGBuiltin.cpp
  clang/lib/Sema/SemaChecking.cpp
  clang/test/CodeGen/builtins-elementwise-math.c
  clang/test/Sema/builtins-elementwise-math.c

Index: clang/test/Sema/builtins-elementwise-math.c
===
--- clang/test/Sema/builtins-elementwise-math.c
+++ clang/test/Sema/builtins-elementwise-math.c
@@ -2,6 +2,7 @@
 
 typedef float float4 __attribute__((ext_vector_type(4)));
 typedef int int3 __attribute__((ext_vector_type(3)));
+typedef unsigned unsigned4 __attribute__((ext_vector_type(4)));
 
 struct Foo {
   char *p;
@@ -11,6 +12,26 @@
 typedef int bar;
 bar b;
 
+void test_builtin_elementwise_abs(int i, double d, float4 v, int3 iv, unsigned u, unsigned4 uv) {
+  struct Foo s = __builtin_elementwise_abs(i);
+  // expected-error@-1 {{initializing 'struct Foo' with an expression of incompatible type 'int'}}
+
+  i = __builtin_elementwise_abs();
+  // expected-error@-1 {{too few arguments to function call, expected 1, have 0}}
+
+  i = __builtin_elementwise_abs(i, i);
+  // expected-error@-1 {{too many arguments to function call, expected 1, have 2}}
+
+  i = __builtin_elementwise_abs(v);
+  // expected-error@-1 {{assigning to 'int' from incompatible type 'float4' (vector of 4 'float' values)}}
+
+  u = __builtin_elementwise_abs(u);
+  // expected-error@-1 {{1st argument must be a signed integer or floating point type (was 'unsigned int')}}
+
+  uv = __builtin_elementwise_abs(uv);
+  // expected-error@-1 {{1st argument must be a signed integer or floating point type (was 'unsigned4' (vector of 4 'unsigned int' values))}}
+}
+
 void test_builtin_elementwise_max(int i, short s, double d, float4 v, int3 iv, int *p) {
   i = __builtin_elementwise_max(p, d);
   // expected-error@-1 {{arguments are of different types ('int *' vs 'double')}}
Index: clang/test/CodeGen/builtins-elementwise-math.c
===
--- clang/test/CodeGen/builtins-elementwise-math.c
+++ clang/test/CodeGen/builtins-elementwise-math.c
@@ -8,12 +8,48 @@
 typedef int bar;
 bar b;
 
+void test_builtin_elementwise_abs(float f1, float f2, double d1, double d2,
+  float4 vf1, float4 vf2, si8 vi1, si8 vi2,
+  long long int i1, long long int i2) {
+  // CHECK-LABEL: define void @test_builtin_elementwise_abs(
+  // CHECK:  [[F1:%.+]] = load float, float* %f1.addr, align 4
+  // CHECK-NEXT:  call float @llvm.fabs.f32(float [[F1]])
+  f2 = __builtin_elementwise_abs(f1);
+
+  // CHECK:  [[D1:%.+]] = load double, double* %d1.addr, align 8
+  // CHECK-NEXT: call double @llvm.fabs.f64(double [[D1]])
+  d2 = __builtin_elementwise_abs(d1);
+
+  // CHECK:  [[VF1:%.+]] = load <4 x float>, <4 x float>* %vf1.addr, align 16
+  // CHECK-NEXT: call <4 x float> @llvm.fabs.v4f32(<4 x float> [[VF1]])
+  vf2 = __builtin_elementwise_abs(vf1);
+
+  // CHECK:  [[I1:%.+]] = load i64, i64* %i1.addr, align 8
+  // CHECK-NEXT: call i64 @llvm.abs.i64(i64 [[I1]], i1 false)
+  i2 = __builtin_elementwise_abs(i1);
+
+  // CHECK:  [[VI1:%.+]] = load <8 x i16>, <8 x i16>* %vi1.addr, align 16
+  // CHECK-NEXT: call <8 x i16> @llvm.abs.v8i16(<8 x i16> [[VI1]], i1 false)
+  vi2 = __builtin_elementwise_abs(vi1);
+
+  // CHECK:  [[CVI2:%.+]] = load <8 x i16>, <8 x i16>* %cvi2, align 16
+  // CHECK-NEXT: call <8 x i16> @llvm.abs.v8i16(<8 x i16> [[CVI2]], i1 false)
+  const si8 cvi2 = vi2;
+  vi2 = __builtin_elementwise_abs(cvi2);
+
+  // CHECK:  [[IA1:%.+]] = load i32, i32 addrspace(1)* @int_as_one, align 4
+  // CHECK-NEXT: call i32 @llvm.abs.i32(i32 [[IA1]], i1 false)
+  b = __builtin_elementwise_abs(int_as_one);
+
+  // CHECK:   call i32 @llvm.abs.i32(i32 -10, i1 false)
+  b = __builtin_elementwise_abs(-10);
+}
+
 void test_builtin_elementwise_max(float f1, float f2, double d1, double d2,
   float4 vf1, float4 vf2, long long int i1,
   long long int i2, si8 vi1, si8 vi2,
   unsigned u1, unsigned u2, u4 vu1, u4 vu2) {
   // CHECK-LABEL: define void @test_builtin_elementwise_max(
-
   // CHECK:  [[F1:%.+]] = load float, float* %f1.addr, align 4
   // CHECK-NEXT: [[F2:%.+]] = load float, float* %f2.addr, align 4
   // CHECK-NEXT:  call float @llvm.maxnum.f32(float %0, float %1)
Index: clang/lib/Sema/SemaChecking.cpp
===
--- clang/lib/Sema/SemaChecking.cpp
+++ clang/lib/Sem

[PATCH] D111986: [Clang] Add elementwise abs builtin.

2021-10-26 Thread Florian Hahn via Phabricator via cfe-commits
fhahn added inline comments.



Comment at: clang/include/clang/Basic/DiagnosticSemaKinds.td:8754
+def err_elementwise_math_invalid_arg_type_2: Error <
+  "argument must have a %0 type, but was %1">;
+

aaron.ballman wrote:
> I feel like we must already have a diagnostic that covers this case...
Updated to use `err_builtin_invalid_arg_type`.



Comment at: clang/lib/Sema/SemaChecking.cpp:16547
+  Expr *A = TheCall->getArg(0);
+  QualType TyA = A->getType();
+

aaron.ballman wrote:
> Should this type undergo the usual promotions?
I'm not sure, but given that we only have a single argument then wouldn't it be 
sufficient to avoid promotion? I don't think promotion to wider types would 
impact the results of the provided builtins.


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D111986/new/

https://reviews.llvm.org/D111986

___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D112532: [Matrix] Replace some err kinds with err_builtin_invalid_arg_type. (NFC)

2021-10-26 Thread Florian Hahn via Phabricator via cfe-commits
fhahn updated this revision to Diff 382413.
fhahn added a comment.

Add comment to int selecting message as suggested.


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D112532/new/

https://reviews.llvm.org/D112532

Files:
  clang/include/clang/Basic/DiagnosticSemaKinds.td
  clang/lib/Sema/SemaChecking.cpp


Index: clang/lib/Sema/SemaChecking.cpp
===
--- clang/lib/Sema/SemaChecking.cpp
+++ clang/lib/Sema/SemaChecking.cpp
@@ -16530,7 +16530,7 @@
 QualType Ty) {
   if (!Ty->getAs() && !ConstantMatrixType::isValidElementType(Ty)) 
{
 S.Diag(Loc, diag::err_builtin_invalid_arg_type)
-<< 1 << "vector, integer or floating point type" << Ty;
+<< 1 << /* vector, integer or float ty*/ 0 << Ty;
 return true;
   }
   return false;
@@ -16578,7 +16578,8 @@
 
   auto *MType = Matrix->getType()->getAs();
   if (!MType) {
-Diag(Matrix->getBeginLoc(), diag::err_builtin_matrix_arg);
+Diag(Matrix->getBeginLoc(), diag::err_builtin_invalid_arg_type)
+<< 1 << /* matrix ty*/ 1 << Matrix->getType();
 return ExprError();
   }
 
@@ -16649,15 +16650,16 @@
   auto *PtrTy = PtrExpr->getType()->getAs();
   QualType ElementTy;
   if (!PtrTy) {
-Diag(PtrExpr->getBeginLoc(), diag::err_builtin_matrix_pointer_arg)
-<< PtrArgIdx + 1;
+Diag(PtrExpr->getBeginLoc(), diag::err_builtin_invalid_arg_type)
+<< PtrArgIdx + 1 << /*pointer to element ty*/ 2 << PtrExpr->getType();
 ArgError = true;
   } else {
 ElementTy = PtrTy->getPointeeType().getUnqualifiedType();
 
 if (!ConstantMatrixType::isValidElementType(ElementTy)) {
-  Diag(PtrExpr->getBeginLoc(), diag::err_builtin_matrix_pointer_arg)
-  << PtrArgIdx + 1;
+  Diag(PtrExpr->getBeginLoc(), diag::err_builtin_invalid_arg_type)
+  << PtrArgIdx + 1 << /* pointer to element ty*/ 2
+  << PtrExpr->getType();
   ArgError = true;
 }
   }
@@ -16756,7 +16758,8 @@
 
   auto *MatrixTy = MatrixExpr->getType()->getAs();
   if (!MatrixTy) {
-Diag(MatrixExpr->getBeginLoc(), diag::err_builtin_matrix_arg) << 0;
+Diag(MatrixExpr->getBeginLoc(), diag::err_builtin_invalid_arg_type)
+<< 1 << /*matrix ty */ 1 << MatrixExpr->getType();
 ArgError = true;
   }
 
@@ -16775,8 +16778,8 @@
   // Check pointer argument.
   auto *PtrTy = PtrExpr->getType()->getAs();
   if (!PtrTy) {
-Diag(PtrExpr->getBeginLoc(), diag::err_builtin_matrix_pointer_arg)
-<< PtrArgIdx + 1;
+Diag(PtrExpr->getBeginLoc(), diag::err_builtin_invalid_arg_type)
+<< PtrArgIdx + 1 << /*pointer to element ty*/ 2 << PtrExpr->getType();
 ArgError = true;
   } else {
 QualType ElementTy = PtrTy->getPointeeType();
Index: clang/include/clang/Basic/DiagnosticSemaKinds.td
===
--- clang/include/clang/Basic/DiagnosticSemaKinds.td
+++ clang/include/clang/Basic/DiagnosticSemaKinds.td
@@ -11304,7 +11304,9 @@
   "'__builtin_launder' is not allowed">;
 
 def err_builtin_invalid_arg_type: Error <
-  "%ordinal0 argument must be a %1 (was %2)">;
+  "%ordinal0 argument must be a "
+  "%select{vector, integer or floating point type|matrix|"
+   "pointer to a valid matrix element type}1 (was %2)">;
 
 def err_builtin_matrix_disabled: Error<
   "matrix types extension is disabled. Pass -fenable-matrix to enable it">;
@@ -11318,11 +11320,8 @@
   "matrix row and column subscripts cannot be separated by any expression">;
 def err_matrix_subscript_comma: Error<
   "comma expressions are not allowed as indices in matrix subscript 
expressions">;
-def err_builtin_matrix_arg: Error<"1st argument must be a matrix">;
 def err_builtin_matrix_scalar_unsigned_arg: Error<
   "%0 argument must be a constant unsigned integer expression">;
-def err_builtin_matrix_pointer_arg: Error<
-  "%ordinal0 argument must be a pointer to a valid matrix element type">;
 def err_builtin_matrix_pointer_arg_mismatch: Error<
   "the pointee of the 2nd argument must match the element type of the 1st 
argument (%0 != %1)">;
 def err_builtin_matrix_store_to_const: Error<


Index: clang/lib/Sema/SemaChecking.cpp
===
--- clang/lib/Sema/SemaChecking.cpp
+++ clang/lib/Sema/SemaChecking.cpp
@@ -16530,7 +16530,7 @@
 QualType Ty) {
   if (!Ty->getAs() && !ConstantMatrixType::isValidElementType(Ty)) {
 S.Diag(Loc, diag::err_builtin_invalid_arg_type)
-<< 1 << "vector, integer or floating point type" << Ty;
+<< 1 << /* vector, integer or float ty*/ 0 << Ty;
 return true;
   }
   return false;
@@ -16578,7 +16578,8 @@
 
   auto *MType = Matrix->getType()->getAs();
   if (!MType) {
-Diag(Matrix->getBeginLoc(), diag::err_builtin_matrix_arg);
+Diag(Matrix->getBeginLoc(), diag::err_builtin_invalid_arg_type)
+<< 

[PATCH] D112532: [Matrix] Replace some err kinds with err_builtin_invalid_arg_type. (NFC)

2021-10-26 Thread Florian Hahn via Phabricator via cfe-commits
fhahn marked an inline comment as done.
fhahn added inline comments.



Comment at: clang/lib/Sema/SemaChecking.cpp:16582
+Diag(Matrix->getBeginLoc(), diag::err_builtin_invalid_arg_type)
+<< 1 << 1 << Matrix->getType();
 return ExprError();

erichkeane wrote:
> 1 nit: On the 'select' lines, please put a /**/ comment next to the integer 
> to explain what it is.  If they were all closer to eachother, I'd suggest 
> doing an enum for them, but the comment should be good enough.
done, thanks!


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D112532/new/

https://reviews.llvm.org/D112532

___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D112532: [Matrix] Replace some err kinds with err_builtin_invalid_arg_type. (NFC)

2021-10-26 Thread Florian Hahn via Phabricator via cfe-commits
This revision was automatically updated to reflect the committed changes.
fhahn marked an inline comment as done.
Closed by commit rGd7fbad0dcfc9: [Matrix] Replace some err kinds with 
err_builtin_invalid_arg_type. (NFC) (authored by fhahn).

Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D112532/new/

https://reviews.llvm.org/D112532

Files:
  clang/include/clang/Basic/DiagnosticSemaKinds.td
  clang/lib/Sema/SemaChecking.cpp


Index: clang/lib/Sema/SemaChecking.cpp
===
--- clang/lib/Sema/SemaChecking.cpp
+++ clang/lib/Sema/SemaChecking.cpp
@@ -16530,7 +16530,7 @@
 QualType Ty) {
   if (!Ty->getAs() && !ConstantMatrixType::isValidElementType(Ty)) 
{
 S.Diag(Loc, diag::err_builtin_invalid_arg_type)
-<< 1 << "vector, integer or floating point type" << Ty;
+<< 1 << /* vector, integer or float ty*/ 0 << Ty;
 return true;
   }
   return false;
@@ -16578,7 +16578,8 @@
 
   auto *MType = Matrix->getType()->getAs();
   if (!MType) {
-Diag(Matrix->getBeginLoc(), diag::err_builtin_matrix_arg);
+Diag(Matrix->getBeginLoc(), diag::err_builtin_invalid_arg_type)
+<< 1 << /* matrix ty*/ 1 << Matrix->getType();
 return ExprError();
   }
 
@@ -16649,15 +16650,16 @@
   auto *PtrTy = PtrExpr->getType()->getAs();
   QualType ElementTy;
   if (!PtrTy) {
-Diag(PtrExpr->getBeginLoc(), diag::err_builtin_matrix_pointer_arg)
-<< PtrArgIdx + 1;
+Diag(PtrExpr->getBeginLoc(), diag::err_builtin_invalid_arg_type)
+<< PtrArgIdx + 1 << /*pointer to element ty*/ 2 << PtrExpr->getType();
 ArgError = true;
   } else {
 ElementTy = PtrTy->getPointeeType().getUnqualifiedType();
 
 if (!ConstantMatrixType::isValidElementType(ElementTy)) {
-  Diag(PtrExpr->getBeginLoc(), diag::err_builtin_matrix_pointer_arg)
-  << PtrArgIdx + 1;
+  Diag(PtrExpr->getBeginLoc(), diag::err_builtin_invalid_arg_type)
+  << PtrArgIdx + 1 << /* pointer to element ty*/ 2
+  << PtrExpr->getType();
   ArgError = true;
 }
   }
@@ -16756,7 +16758,8 @@
 
   auto *MatrixTy = MatrixExpr->getType()->getAs();
   if (!MatrixTy) {
-Diag(MatrixExpr->getBeginLoc(), diag::err_builtin_matrix_arg) << 0;
+Diag(MatrixExpr->getBeginLoc(), diag::err_builtin_invalid_arg_type)
+<< 1 << /*matrix ty */ 1 << MatrixExpr->getType();
 ArgError = true;
   }
 
@@ -16775,8 +16778,8 @@
   // Check pointer argument.
   auto *PtrTy = PtrExpr->getType()->getAs();
   if (!PtrTy) {
-Diag(PtrExpr->getBeginLoc(), diag::err_builtin_matrix_pointer_arg)
-<< PtrArgIdx + 1;
+Diag(PtrExpr->getBeginLoc(), diag::err_builtin_invalid_arg_type)
+<< PtrArgIdx + 1 << /*pointer to element ty*/ 2 << PtrExpr->getType();
 ArgError = true;
   } else {
 QualType ElementTy = PtrTy->getPointeeType();
Index: clang/include/clang/Basic/DiagnosticSemaKinds.td
===
--- clang/include/clang/Basic/DiagnosticSemaKinds.td
+++ clang/include/clang/Basic/DiagnosticSemaKinds.td
@@ -11304,7 +11304,9 @@
   "'__builtin_launder' is not allowed">;
 
 def err_builtin_invalid_arg_type: Error <
-  "%ordinal0 argument must be a %1 (was %2)">;
+  "%ordinal0 argument must be a "
+  "%select{vector, integer or floating point type|matrix|"
+   "pointer to a valid matrix element type}1 (was %2)">;
 
 def err_builtin_matrix_disabled: Error<
   "matrix types extension is disabled. Pass -fenable-matrix to enable it">;
@@ -11318,11 +11320,8 @@
   "matrix row and column subscripts cannot be separated by any expression">;
 def err_matrix_subscript_comma: Error<
   "comma expressions are not allowed as indices in matrix subscript 
expressions">;
-def err_builtin_matrix_arg: Error<"1st argument must be a matrix">;
 def err_builtin_matrix_scalar_unsigned_arg: Error<
   "%0 argument must be a constant unsigned integer expression">;
-def err_builtin_matrix_pointer_arg: Error<
-  "%ordinal0 argument must be a pointer to a valid matrix element type">;
 def err_builtin_matrix_pointer_arg_mismatch: Error<
   "the pointee of the 2nd argument must match the element type of the 1st 
argument (%0 != %1)">;
 def err_builtin_matrix_store_to_const: Error<


Index: clang/lib/Sema/SemaChecking.cpp
===
--- clang/lib/Sema/SemaChecking.cpp
+++ clang/lib/Sema/SemaChecking.cpp
@@ -16530,7 +16530,7 @@
 QualType Ty) {
   if (!Ty->getAs() && !ConstantMatrixType::isValidElementType(Ty)) {
 S.Diag(Loc, diag::err_builtin_invalid_arg_type)
-<< 1 << "vector, integer or floating point type" << Ty;
+<< 1 << /* vector, integer or float ty*/ 0 << Ty;
 return true;
   }
   return false;
@@ -16578,7 +16578,8 @@
 
   auto *MType = Matrix->getType()->getAs();
   if (!MType) {
-Diag(Matrix->getBe

[PATCH] D111986: [Clang] Add elementwise abs builtin.

2021-10-26 Thread Florian Hahn via Phabricator via cfe-commits
fhahn updated this revision to Diff 382443.
fhahn added a comment.

Apply UsualUnaryConversions to input argument.


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D111986/new/

https://reviews.llvm.org/D111986

Files:
  clang/include/clang/Basic/Builtins.def
  clang/include/clang/Basic/DiagnosticSemaKinds.td
  clang/include/clang/Sema/Sema.h
  clang/lib/CodeGen/CGBuiltin.cpp
  clang/lib/Sema/SemaChecking.cpp
  clang/test/CodeGen/builtins-elementwise-math.c
  clang/test/Sema/builtins-elementwise-math.c
  clang/test/SemaCXX/builtins-elementwise-math.cpp

Index: clang/test/SemaCXX/builtins-elementwise-math.cpp
===
--- clang/test/SemaCXX/builtins-elementwise-math.cpp
+++ clang/test/SemaCXX/builtins-elementwise-math.cpp
@@ -14,6 +14,13 @@
 
 // expected-no-diagnostics
 
+void test_builtin_elementwise_abs() {
+  const int a = 2;
+  int b = 1;
+  static_assert(!is_const::value);
+  static_assert(!is_const::value);
+}
+
 void test_builtin_elementwise_max() {
   const int a = 2;
   int b = 1;
Index: clang/test/Sema/builtins-elementwise-math.c
===
--- clang/test/Sema/builtins-elementwise-math.c
+++ clang/test/Sema/builtins-elementwise-math.c
@@ -2,6 +2,7 @@
 
 typedef float float4 __attribute__((ext_vector_type(4)));
 typedef int int3 __attribute__((ext_vector_type(3)));
+typedef unsigned unsigned4 __attribute__((ext_vector_type(4)));
 
 struct Foo {
   char *p;
@@ -11,6 +12,26 @@
 typedef int bar;
 bar b;
 
+void test_builtin_elementwise_abs(int i, double d, float4 v, int3 iv, unsigned u, unsigned4 uv) {
+  struct Foo s = __builtin_elementwise_abs(i);
+  // expected-error@-1 {{initializing 'struct Foo' with an expression of incompatible type 'int'}}
+
+  i = __builtin_elementwise_abs();
+  // expected-error@-1 {{too few arguments to function call, expected 1, have 0}}
+
+  i = __builtin_elementwise_abs(i, i);
+  // expected-error@-1 {{too many arguments to function call, expected 1, have 2}}
+
+  i = __builtin_elementwise_abs(v);
+  // expected-error@-1 {{assigning to 'int' from incompatible type 'float4' (vector of 4 'float' values)}}
+
+  u = __builtin_elementwise_abs(u);
+  // expected-error@-1 {{1st argument must be a signed integer or floating point type (was 'unsigned int')}}
+
+  uv = __builtin_elementwise_abs(uv);
+  // expected-error@-1 {{1st argument must be a signed integer or floating point type (was 'unsigned4' (vector of 4 'unsigned int' values))}}
+}
+
 void test_builtin_elementwise_max(int i, short s, double d, float4 v, int3 iv, int *p) {
   i = __builtin_elementwise_max(p, d);
   // expected-error@-1 {{arguments are of different types ('int *' vs 'double')}}
Index: clang/test/CodeGen/builtins-elementwise-math.c
===
--- clang/test/CodeGen/builtins-elementwise-math.c
+++ clang/test/CodeGen/builtins-elementwise-math.c
@@ -8,12 +8,54 @@
 typedef int bar;
 bar b;
 
+void test_builtin_elementwise_abs(float f1, float f2, double d1, double d2,
+  float4 vf1, float4 vf2, si8 vi1, si8 vi2,
+  long long int i1, long long int i2, short si) {
+  // CHECK-LABEL: define void @test_builtin_elementwise_abs(
+  // CHECK:  [[F1:%.+]] = load float, float* %f1.addr, align 4
+  // CHECK-NEXT:  call float @llvm.fabs.f32(float [[F1]])
+  f2 = __builtin_elementwise_abs(f1);
+
+  // CHECK:  [[D1:%.+]] = load double, double* %d1.addr, align 8
+  // CHECK-NEXT: call double @llvm.fabs.f64(double [[D1]])
+  d2 = __builtin_elementwise_abs(d1);
+
+  // CHECK:  [[VF1:%.+]] = load <4 x float>, <4 x float>* %vf1.addr, align 16
+  // CHECK-NEXT: call <4 x float> @llvm.fabs.v4f32(<4 x float> [[VF1]])
+  vf2 = __builtin_elementwise_abs(vf1);
+
+  // CHECK:  [[I1:%.+]] = load i64, i64* %i1.addr, align 8
+  // CHECK-NEXT: call i64 @llvm.abs.i64(i64 [[I1]], i1 false)
+  i2 = __builtin_elementwise_abs(i1);
+
+  // CHECK:  [[VI1:%.+]] = load <8 x i16>, <8 x i16>* %vi1.addr, align 16
+  // CHECK-NEXT: call <8 x i16> @llvm.abs.v8i16(<8 x i16> [[VI1]], i1 false)
+  vi2 = __builtin_elementwise_abs(vi1);
+
+  // CHECK:  [[CVI2:%.+]] = load <8 x i16>, <8 x i16>* %cvi2, align 16
+  // CHECK-NEXT: call <8 x i16> @llvm.abs.v8i16(<8 x i16> [[CVI2]], i1 false)
+  const si8 cvi2 = vi2;
+  vi2 = __builtin_elementwise_abs(cvi2);
+
+  // CHECK:  [[IA1:%.+]] = load i32, i32 addrspace(1)* @int_as_one, align 4
+  // CHECK-NEXT: call i32 @llvm.abs.i32(i32 [[IA1]], i1 false)
+  b = __builtin_elementwise_abs(int_as_one);
+
+  // CHECK:   call i32 @llvm.abs.i32(i32 -10, i1 false)
+  b = __builtin_elementwise_abs(-10);
+
+  // CHECK:  [[SI:%.+]] = load i16, i16* %si.addr, align 2
+  // CHECK-NEXT: [[SI_EXT:%.+]] = sext i16 [[SI]] to i32
+  // CHECK-NEXT: [[RES:%.+]] = call i32 @llvm.abs.i32(i32 [[SI_EXT]], i1 false)
+  // CHECK-NEXT: 

[PATCH] D111986: [Clang] Add elementwise abs builtin.

2021-10-26 Thread Florian Hahn via Phabricator via cfe-commits
fhahn marked an inline comment as done.
fhahn added inline comments.



Comment at: clang/lib/Sema/SemaChecking.cpp:16547
+  Expr *A = TheCall->getArg(0);
+  QualType TyA = A->getType();
+

aaron.ballman wrote:
> fhahn wrote:
> > aaron.ballman wrote:
> > > Should this type undergo the usual promotions?
> > I'm not sure, but given that we only have a single argument then wouldn't 
> > it be sufficient to avoid promotion? I don't think promotion to wider types 
> > would impact the results of the provided builtins.
> You set the type of the call to be the type of the argument, which means 
> passing in a `const int` will result in a `const int` that's observable and 
> probably unexpected. e.g. this will fail,
> ```
> const int a = -12;
> static_assert(!std::is_const_v);
> ```
> (This can come up with overload resolution or in template specializations.)
Ah right. I originally was planning on just using `getUnqualifiedType`, but for 
consistency it seems better to just apply the usual unary conversions. I also 
added the test above and a codegen tests with `short`.


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D111986/new/

https://reviews.llvm.org/D111986

___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D111986: [Clang] Add elementwise abs builtin.

2021-10-26 Thread Florian Hahn via Phabricator via cfe-commits
fhahn updated this revision to Diff 382445.
fhahn marked an inline comment as done.
fhahn added a comment.

add comment to arg of Diag message


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D111986/new/

https://reviews.llvm.org/D111986

Files:
  clang/include/clang/Basic/Builtins.def
  clang/include/clang/Basic/DiagnosticSemaKinds.td
  clang/include/clang/Sema/Sema.h
  clang/lib/CodeGen/CGBuiltin.cpp
  clang/lib/Sema/SemaChecking.cpp
  clang/test/CodeGen/builtins-elementwise-math.c
  clang/test/Sema/builtins-elementwise-math.c
  clang/test/SemaCXX/builtins-elementwise-math.cpp

Index: clang/test/SemaCXX/builtins-elementwise-math.cpp
===
--- clang/test/SemaCXX/builtins-elementwise-math.cpp
+++ clang/test/SemaCXX/builtins-elementwise-math.cpp
@@ -14,6 +14,13 @@
 
 // expected-no-diagnostics
 
+void test_builtin_elementwise_abs() {
+  const int a = 2;
+  int b = 1;
+  static_assert(!is_const::value);
+  static_assert(!is_const::value);
+}
+
 void test_builtin_elementwise_max() {
   const int a = 2;
   int b = 1;
Index: clang/test/Sema/builtins-elementwise-math.c
===
--- clang/test/Sema/builtins-elementwise-math.c
+++ clang/test/Sema/builtins-elementwise-math.c
@@ -2,6 +2,7 @@
 
 typedef float float4 __attribute__((ext_vector_type(4)));
 typedef int int3 __attribute__((ext_vector_type(3)));
+typedef unsigned unsigned4 __attribute__((ext_vector_type(4)));
 
 struct Foo {
   char *p;
@@ -11,6 +12,26 @@
 typedef int bar;
 bar b;
 
+void test_builtin_elementwise_abs(int i, double d, float4 v, int3 iv, unsigned u, unsigned4 uv) {
+  struct Foo s = __builtin_elementwise_abs(i);
+  // expected-error@-1 {{initializing 'struct Foo' with an expression of incompatible type 'int'}}
+
+  i = __builtin_elementwise_abs();
+  // expected-error@-1 {{too few arguments to function call, expected 1, have 0}}
+
+  i = __builtin_elementwise_abs(i, i);
+  // expected-error@-1 {{too many arguments to function call, expected 1, have 2}}
+
+  i = __builtin_elementwise_abs(v);
+  // expected-error@-1 {{assigning to 'int' from incompatible type 'float4' (vector of 4 'float' values)}}
+
+  u = __builtin_elementwise_abs(u);
+  // expected-error@-1 {{1st argument must be a signed integer or floating point type (was 'unsigned int')}}
+
+  uv = __builtin_elementwise_abs(uv);
+  // expected-error@-1 {{1st argument must be a signed integer or floating point type (was 'unsigned4' (vector of 4 'unsigned int' values))}}
+}
+
 void test_builtin_elementwise_max(int i, short s, double d, float4 v, int3 iv, int *p) {
   i = __builtin_elementwise_max(p, d);
   // expected-error@-1 {{arguments are of different types ('int *' vs 'double')}}
Index: clang/test/CodeGen/builtins-elementwise-math.c
===
--- clang/test/CodeGen/builtins-elementwise-math.c
+++ clang/test/CodeGen/builtins-elementwise-math.c
@@ -8,12 +8,54 @@
 typedef int bar;
 bar b;
 
+void test_builtin_elementwise_abs(float f1, float f2, double d1, double d2,
+  float4 vf1, float4 vf2, si8 vi1, si8 vi2,
+  long long int i1, long long int i2, short si) {
+  // CHECK-LABEL: define void @test_builtin_elementwise_abs(
+  // CHECK:  [[F1:%.+]] = load float, float* %f1.addr, align 4
+  // CHECK-NEXT:  call float @llvm.fabs.f32(float [[F1]])
+  f2 = __builtin_elementwise_abs(f1);
+
+  // CHECK:  [[D1:%.+]] = load double, double* %d1.addr, align 8
+  // CHECK-NEXT: call double @llvm.fabs.f64(double [[D1]])
+  d2 = __builtin_elementwise_abs(d1);
+
+  // CHECK:  [[VF1:%.+]] = load <4 x float>, <4 x float>* %vf1.addr, align 16
+  // CHECK-NEXT: call <4 x float> @llvm.fabs.v4f32(<4 x float> [[VF1]])
+  vf2 = __builtin_elementwise_abs(vf1);
+
+  // CHECK:  [[I1:%.+]] = load i64, i64* %i1.addr, align 8
+  // CHECK-NEXT: call i64 @llvm.abs.i64(i64 [[I1]], i1 false)
+  i2 = __builtin_elementwise_abs(i1);
+
+  // CHECK:  [[VI1:%.+]] = load <8 x i16>, <8 x i16>* %vi1.addr, align 16
+  // CHECK-NEXT: call <8 x i16> @llvm.abs.v8i16(<8 x i16> [[VI1]], i1 false)
+  vi2 = __builtin_elementwise_abs(vi1);
+
+  // CHECK:  [[CVI2:%.+]] = load <8 x i16>, <8 x i16>* %cvi2, align 16
+  // CHECK-NEXT: call <8 x i16> @llvm.abs.v8i16(<8 x i16> [[CVI2]], i1 false)
+  const si8 cvi2 = vi2;
+  vi2 = __builtin_elementwise_abs(cvi2);
+
+  // CHECK:  [[IA1:%.+]] = load i32, i32 addrspace(1)* @int_as_one, align 4
+  // CHECK-NEXT: call i32 @llvm.abs.i32(i32 [[IA1]], i1 false)
+  b = __builtin_elementwise_abs(int_as_one);
+
+  // CHECK:   call i32 @llvm.abs.i32(i32 -10, i1 false)
+  b = __builtin_elementwise_abs(-10);
+
+  // CHECK:  [[SI:%.+]] = load i16, i16* %si.addr, align 2
+  // CHECK-NEXT: [[SI_EXT:%.+]] = sext i16 [[SI]] to i32
+  // CHECK-NEXT: [[RES:%.+]] = call i32 @llvm.abs.i32(i32 [[SI_EXT]], 

[PATCH] D111986: [Clang] Add elementwise abs builtin.

2021-10-27 Thread Florian Hahn via Phabricator via cfe-commits
This revision was automatically updated to reflect the committed changes.
Closed by commit rG01870d51b848: [Clang] Add elementwise abs builtin. (authored 
by fhahn).

Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D111986/new/

https://reviews.llvm.org/D111986

Files:
  clang/include/clang/Basic/Builtins.def
  clang/include/clang/Basic/DiagnosticSemaKinds.td
  clang/include/clang/Sema/Sema.h
  clang/lib/CodeGen/CGBuiltin.cpp
  clang/lib/Sema/SemaChecking.cpp
  clang/test/CodeGen/builtins-elementwise-math.c
  clang/test/Sema/builtins-elementwise-math.c
  clang/test/SemaCXX/builtins-elementwise-math.cpp

Index: clang/test/SemaCXX/builtins-elementwise-math.cpp
===
--- clang/test/SemaCXX/builtins-elementwise-math.cpp
+++ clang/test/SemaCXX/builtins-elementwise-math.cpp
@@ -14,6 +14,13 @@
 
 // expected-no-diagnostics
 
+void test_builtin_elementwise_abs() {
+  const int a = 2;
+  int b = 1;
+  static_assert(!is_const::value);
+  static_assert(!is_const::value);
+}
+
 void test_builtin_elementwise_max() {
   const int a = 2;
   int b = 1;
Index: clang/test/Sema/builtins-elementwise-math.c
===
--- clang/test/Sema/builtins-elementwise-math.c
+++ clang/test/Sema/builtins-elementwise-math.c
@@ -2,6 +2,7 @@
 
 typedef float float4 __attribute__((ext_vector_type(4)));
 typedef int int3 __attribute__((ext_vector_type(3)));
+typedef unsigned unsigned4 __attribute__((ext_vector_type(4)));
 
 struct Foo {
   char *p;
@@ -11,6 +12,26 @@
 typedef int bar;
 bar b;
 
+void test_builtin_elementwise_abs(int i, double d, float4 v, int3 iv, unsigned u, unsigned4 uv) {
+  struct Foo s = __builtin_elementwise_abs(i);
+  // expected-error@-1 {{initializing 'struct Foo' with an expression of incompatible type 'int'}}
+
+  i = __builtin_elementwise_abs();
+  // expected-error@-1 {{too few arguments to function call, expected 1, have 0}}
+
+  i = __builtin_elementwise_abs(i, i);
+  // expected-error@-1 {{too many arguments to function call, expected 1, have 2}}
+
+  i = __builtin_elementwise_abs(v);
+  // expected-error@-1 {{assigning to 'int' from incompatible type 'float4' (vector of 4 'float' values)}}
+
+  u = __builtin_elementwise_abs(u);
+  // expected-error@-1 {{1st argument must be a signed integer or floating point type (was 'unsigned int')}}
+
+  uv = __builtin_elementwise_abs(uv);
+  // expected-error@-1 {{1st argument must be a signed integer or floating point type (was 'unsigned4' (vector of 4 'unsigned int' values))}}
+}
+
 void test_builtin_elementwise_max(int i, short s, double d, float4 v, int3 iv, int *p) {
   i = __builtin_elementwise_max(p, d);
   // expected-error@-1 {{arguments are of different types ('int *' vs 'double')}}
Index: clang/test/CodeGen/builtins-elementwise-math.c
===
--- clang/test/CodeGen/builtins-elementwise-math.c
+++ clang/test/CodeGen/builtins-elementwise-math.c
@@ -8,12 +8,54 @@
 typedef int bar;
 bar b;
 
+void test_builtin_elementwise_abs(float f1, float f2, double d1, double d2,
+  float4 vf1, float4 vf2, si8 vi1, si8 vi2,
+  long long int i1, long long int i2, short si) {
+  // CHECK-LABEL: define void @test_builtin_elementwise_abs(
+  // CHECK:  [[F1:%.+]] = load float, float* %f1.addr, align 4
+  // CHECK-NEXT:  call float @llvm.fabs.f32(float [[F1]])
+  f2 = __builtin_elementwise_abs(f1);
+
+  // CHECK:  [[D1:%.+]] = load double, double* %d1.addr, align 8
+  // CHECK-NEXT: call double @llvm.fabs.f64(double [[D1]])
+  d2 = __builtin_elementwise_abs(d1);
+
+  // CHECK:  [[VF1:%.+]] = load <4 x float>, <4 x float>* %vf1.addr, align 16
+  // CHECK-NEXT: call <4 x float> @llvm.fabs.v4f32(<4 x float> [[VF1]])
+  vf2 = __builtin_elementwise_abs(vf1);
+
+  // CHECK:  [[I1:%.+]] = load i64, i64* %i1.addr, align 8
+  // CHECK-NEXT: call i64 @llvm.abs.i64(i64 [[I1]], i1 false)
+  i2 = __builtin_elementwise_abs(i1);
+
+  // CHECK:  [[VI1:%.+]] = load <8 x i16>, <8 x i16>* %vi1.addr, align 16
+  // CHECK-NEXT: call <8 x i16> @llvm.abs.v8i16(<8 x i16> [[VI1]], i1 false)
+  vi2 = __builtin_elementwise_abs(vi1);
+
+  // CHECK:  [[CVI2:%.+]] = load <8 x i16>, <8 x i16>* %cvi2, align 16
+  // CHECK-NEXT: call <8 x i16> @llvm.abs.v8i16(<8 x i16> [[CVI2]], i1 false)
+  const si8 cvi2 = vi2;
+  vi2 = __builtin_elementwise_abs(cvi2);
+
+  // CHECK:  [[IA1:%.+]] = load i32, i32 addrspace(1)* @int_as_one, align 4
+  // CHECK-NEXT: call i32 @llvm.abs.i32(i32 [[IA1]], i1 false)
+  b = __builtin_elementwise_abs(int_as_one);
+
+  // CHECK:   call i32 @llvm.abs.i32(i32 -10, i1 false)
+  b = __builtin_elementwise_abs(-10);
+
+  // CHECK:  [[SI:%.+]] = load i16, i16* %si.addr, align 2
+  // CHECK-NEXT: [[SI_EXT:%.+]] = sext i16 [[SI]] to i32
+  // CHECK-NEXT: [[RES:%.+]] = call i32 @llvm.ab

[PATCH] D112001: [Clang] Add min/max reduction builtins.

2021-11-01 Thread Florian Hahn via Phabricator via cfe-commits
fhahn updated this revision to Diff 383756.
fhahn added a comment.

rebase on top of recent changes.


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D112001/new/

https://reviews.llvm.org/D112001

Files:
  clang/include/clang/Basic/Builtins.def
  clang/include/clang/Basic/DiagnosticSemaKinds.td
  clang/include/clang/Sema/Sema.h
  clang/lib/CodeGen/CGBuiltin.cpp
  clang/lib/Sema/SemaChecking.cpp
  clang/test/CodeGen/builtins-reduction-math.c
  clang/test/Sema/builtins-reduction-math.c

Index: clang/test/Sema/builtins-reduction-math.c
===
--- /dev/null
+++ clang/test/Sema/builtins-reduction-math.c
@@ -0,0 +1,37 @@
+// RUN: %clang_cc1 %s -pedantic -verify -triple=x86_64-apple-darwin9
+
+typedef float float4 __attribute__((ext_vector_type(4)));
+typedef int int3 __attribute__((ext_vector_type(3)));
+typedef unsigned unsigned4 __attribute__((ext_vector_type(4)));
+
+struct Foo {
+  char *p;
+};
+
+void test_builtin_reduce_max(int i, float4 v, int3 iv) {
+  struct Foo s = __builtin_reduce_max(iv);
+  // expected-error@-1 {{initializing 'struct Foo' with an expression of incompatible type 'int3' (vector of 3 'int' values)}}
+
+  i = __builtin_reduce_max(v, v);
+  // expected-error@-1 {{too many arguments to function call, expected 1, have 2}}
+
+  i = __builtin_reduce_max();
+  // expected-error@-1 {{too few arguments to function call, expected 1, have 0}}
+
+  i = __builtin_reduce_max(i);
+  // expected-error@-1 {{1st argument must be a vector type (was 'int')}}
+}
+
+void test_builtin_reduce_min(int i, float4 v, int3 iv) {
+  struct Foo s = __builtin_reduce_min(iv);
+  // expected-error@-1 {{initializing 'struct Foo' with an expression of incompatible type 'int3' (vector of 3 'int' values)}}
+
+  i = __builtin_reduce_min(v, v);
+  // expected-error@-1 {{too many arguments to function call, expected 1, have 2}}
+
+  i = __builtin_reduce_min();
+  // expected-error@-1 {{too few arguments to function call, expected 1, have 0}}
+
+  i = __builtin_reduce_min(i);
+  // expected-error@-1 {{1st argument must be a vector type (was 'int')}}
+}
Index: clang/test/CodeGen/builtins-reduction-math.c
===
--- /dev/null
+++ clang/test/CodeGen/builtins-reduction-math.c
@@ -0,0 +1,59 @@
+// RUN: %clang_cc1 -triple x86_64-apple-darwin %s -emit-llvm -disable-llvm-passes -o - | FileCheck %s
+
+typedef float float4 __attribute__((ext_vector_type(4)));
+typedef short int si8 __attribute__((ext_vector_type(8)));
+typedef unsigned int u4 __attribute__((ext_vector_type(4)));
+
+__attribute__((address_space(1))) float4 vf1_as_one;
+
+void test_builtin_reduce_max(float4 vf1, si8 vi1, u4 vu1) {
+  // CHECK-LABEL: define void @test_builtin_reduce_max(
+  // CHECK:  [[VF1:%.+]] = load <4 x float>, <4 x float>* %vf1.addr, align 16
+  // CHECK-NEXT: call float @llvm.vector.reduce.fmax.v4f32(<4 x float> [[VF1]])
+  float r1 = __builtin_reduce_max(vf1);
+
+  // CHECK:  [[VI1:%.+]] = load <8 x i16>, <8 x i16>* %vi1.addr, align 16
+  // CHECK-NEXT: call i16 @llvm.vector.reduce.smax.v8i16(<8 x i16> [[VI1]])
+  short r2 = __builtin_reduce_max(vi1);
+
+  // CHECK:  [[VU1:%.+]] = load <4 x i32>, <4 x i32>* %vu1.addr, align 16
+  // CHECK-NEXT: call i32 @llvm.vector.reduce.umax.v4i32(<4 x i32> [[VU1]])
+  unsigned r3 = __builtin_reduce_max(vu1);
+
+  // CHECK:  [[VF1_AS1:%.+]] = load <4 x float>, <4 x float> addrspace(1)* @vf1_as_one, align 16
+  // CHECK-NEXT: [[RDX1:%.+]] = call float @llvm.vector.reduce.fmax.v4f32(<4 x float> [[VF1_AS1]])
+  // CHECK-NEXT: fpext float [[RDX1]] to double
+  const double r4 = __builtin_reduce_max(vf1_as_one);
+
+  // CHECK:  [[CVI1:%.+]] = load <8 x i16>, <8 x i16>* %cvi1, align 16
+  // CHECK-NEXT: [[RDX2:%.+]] = call i16 @llvm.vector.reduce.smax.v8i16(<8 x i16> [[CVI1]])
+  // CHECK-NEXT: sext i16 [[RDX2]] to i64
+  const si8 cvi1 = vi1;
+  unsigned long long r5 = __builtin_reduce_max(cvi1);
+}
+
+void test_builtin_reduce_min(float4 vf1, si8 vi1, u4 vu1) {
+  // CHECK-LABEL: define void @test_builtin_reduce_min(
+  // CHECK:  [[VF1:%.+]] = load <4 x float>, <4 x float>* %vf1.addr, align 16
+  // CHECK-NEXT: call float @llvm.vector.reduce.fmin.v4f32(<4 x float> [[VF1]])
+  float r1 = __builtin_reduce_min(vf1);
+
+  // CHECK:  [[VI1:%.+]] = load <8 x i16>, <8 x i16>* %vi1.addr, align 16
+  // CHECK-NEXT: call i16 @llvm.vector.reduce.smin.v8i16(<8 x i16> [[VI1]])
+  short r2 = __builtin_reduce_min(vi1);
+
+  // CHECK:  [[VU1:%.+]] = load <4 x i32>, <4 x i32>* %vu1.addr, align 16
+  // CHECK-NEXT: call i32 @llvm.vector.reduce.umin.v4i32(<4 x i32> [[VU1]])
+  unsigned r3 = __builtin_reduce_min(vu1);
+
+  // CHECK:  [[VF1_AS1:%.+]] = load <4 x float>, <4 x float> addrspace(1)* @vf1_as_one, align 16
+  // CHECK-NEXT: [[RDX1:%.+]] = call float @llvm.vector.reduce.fmin.v4f32(<4 x float> [[VF1_AS1]])
+  // CHECK-NEXT: fpe

[PATCH] D112001: [Clang] Add min/max reduction builtins.

2021-11-01 Thread Florian Hahn via Phabricator via cfe-commits
fhahn updated this revision to Diff 383900.
fhahn added a comment.

In D112001#3099965 , @aaron.ballman 
wrote:

> Precommit CI looks to be failing.
>
>   
> /var/lib/buildkite-agent/builds/llvm-project/clang/test/CodeGen/builtins-reduction-math.c:13:9:
>  error: initializing 'float' with an expression of incompatible type 'float4' 
> (vector of 4 'float' values)
>   
> float r1 = __builtin_reduce_max(vf1);

The last version of the patch did not correctly set the return type to the 
element type. That should be fixed now!


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D112001/new/

https://reviews.llvm.org/D112001

Files:
  clang/include/clang/Basic/Builtins.def
  clang/include/clang/Basic/DiagnosticSemaKinds.td
  clang/include/clang/Sema/Sema.h
  clang/lib/CodeGen/CGBuiltin.cpp
  clang/lib/Sema/SemaChecking.cpp
  clang/test/CodeGen/builtins-reduction-math.c
  clang/test/Sema/builtins-reduction-math.c

Index: clang/test/Sema/builtins-reduction-math.c
===
--- /dev/null
+++ clang/test/Sema/builtins-reduction-math.c
@@ -0,0 +1,37 @@
+// RUN: %clang_cc1 %s -pedantic -verify -triple=x86_64-apple-darwin9
+
+typedef float float4 __attribute__((ext_vector_type(4)));
+typedef int int3 __attribute__((ext_vector_type(3)));
+typedef unsigned unsigned4 __attribute__((ext_vector_type(4)));
+
+struct Foo {
+  char *p;
+};
+
+void test_builtin_reduce_max(int i, float4 v, int3 iv) {
+  struct Foo s = __builtin_reduce_max(iv);
+  // expected-error@-1 {{initializing 'struct Foo' with an expression of incompatible type 'int'}}
+
+  i = __builtin_reduce_max(v, v);
+  // expected-error@-1 {{too many arguments to function call, expected 1, have 2}}
+
+  i = __builtin_reduce_max();
+  // expected-error@-1 {{too few arguments to function call, expected 1, have 0}}
+
+  i = __builtin_reduce_max(i);
+  // expected-error@-1 {{1st argument must be a vector type (was 'int')}}
+}
+
+void test_builtin_reduce_min(int i, float4 v, int3 iv) {
+  struct Foo s = __builtin_reduce_min(iv);
+  // expected-error@-1 {{initializing 'struct Foo' with an expression of incompatible type 'int'}}
+
+  i = __builtin_reduce_min(v, v);
+  // expected-error@-1 {{too many arguments to function call, expected 1, have 2}}
+
+  i = __builtin_reduce_min();
+  // expected-error@-1 {{too few arguments to function call, expected 1, have 0}}
+
+  i = __builtin_reduce_min(i);
+  // expected-error@-1 {{1st argument must be a vector type (was 'int')}}
+}
Index: clang/test/CodeGen/builtins-reduction-math.c
===
--- /dev/null
+++ clang/test/CodeGen/builtins-reduction-math.c
@@ -0,0 +1,59 @@
+// RUN: %clang_cc1 -triple x86_64-apple-darwin %s -emit-llvm -disable-llvm-passes -o - | FileCheck %s
+
+typedef float float4 __attribute__((ext_vector_type(4)));
+typedef short int si8 __attribute__((ext_vector_type(8)));
+typedef unsigned int u4 __attribute__((ext_vector_type(4)));
+
+__attribute__((address_space(1))) float4 vf1_as_one;
+
+void test_builtin_reduce_max(float4 vf1, si8 vi1, u4 vu1) {
+  // CHECK-LABEL: define void @test_builtin_reduce_max(
+  // CHECK:  [[VF1:%.+]] = load <4 x float>, <4 x float>* %vf1.addr, align 16
+  // CHECK-NEXT: call float @llvm.vector.reduce.fmax.v4f32(<4 x float> [[VF1]])
+  float r1 = __builtin_reduce_max(vf1);
+
+  // CHECK:  [[VI1:%.+]] = load <8 x i16>, <8 x i16>* %vi1.addr, align 16
+  // CHECK-NEXT: call i16 @llvm.vector.reduce.smax.v8i16(<8 x i16> [[VI1]])
+  short r2 = __builtin_reduce_max(vi1);
+
+  // CHECK:  [[VU1:%.+]] = load <4 x i32>, <4 x i32>* %vu1.addr, align 16
+  // CHECK-NEXT: call i32 @llvm.vector.reduce.umax.v4i32(<4 x i32> [[VU1]])
+  unsigned r3 = __builtin_reduce_max(vu1);
+
+  // CHECK:  [[VF1_AS1:%.+]] = load <4 x float>, <4 x float> addrspace(1)* @vf1_as_one, align 16
+  // CHECK-NEXT: [[RDX1:%.+]] = call float @llvm.vector.reduce.fmax.v4f32(<4 x float> [[VF1_AS1]])
+  // CHECK-NEXT: fpext float [[RDX1]] to double
+  const double r4 = __builtin_reduce_max(vf1_as_one);
+
+  // CHECK:  [[CVI1:%.+]] = load <8 x i16>, <8 x i16>* %cvi1, align 16
+  // CHECK-NEXT: [[RDX2:%.+]] = call i16 @llvm.vector.reduce.smax.v8i16(<8 x i16> [[CVI1]])
+  // CHECK-NEXT: sext i16 [[RDX2]] to i64
+  const si8 cvi1 = vi1;
+  unsigned long long r5 = __builtin_reduce_max(cvi1);
+}
+
+void test_builtin_reduce_min(float4 vf1, si8 vi1, u4 vu1) {
+  // CHECK-LABEL: define void @test_builtin_reduce_min(
+  // CHECK:  [[VF1:%.+]] = load <4 x float>, <4 x float>* %vf1.addr, align 16
+  // CHECK-NEXT: call float @llvm.vector.reduce.fmin.v4f32(<4 x float> [[VF1]])
+  float r1 = __builtin_reduce_min(vf1);
+
+  // CHECK:  [[VI1:%.+]] = load <8 x i16>, <8 x i16>* %vi1.addr, align 16
+  // CHECK-NEXT: call i16 @llvm.vector.reduce.smin.v8i16(<8 x i16> [[VI1]])
+  short r2 = __builtin_reduce_min(vi1);
+
+  // CH

[PATCH] D112001: [Clang] Add min/max reduction builtins.

2021-11-02 Thread Florian Hahn via Phabricator via cfe-commits
This revision was landed with ongoing or failed builds.
This revision was automatically updated to reflect the committed changes.
Closed by commit rG7999355106fb: [Clang] Add min/max reduction builtins. 
(authored by fhahn).

Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D112001/new/

https://reviews.llvm.org/D112001

Files:
  clang/include/clang/Basic/Builtins.def
  clang/include/clang/Basic/DiagnosticSemaKinds.td
  clang/include/clang/Sema/Sema.h
  clang/lib/CodeGen/CGBuiltin.cpp
  clang/lib/Sema/SemaChecking.cpp
  clang/test/CodeGen/builtins-reduction-math.c
  clang/test/Sema/builtins-reduction-math.c

Index: clang/test/Sema/builtins-reduction-math.c
===
--- /dev/null
+++ clang/test/Sema/builtins-reduction-math.c
@@ -0,0 +1,37 @@
+// RUN: %clang_cc1 %s -pedantic -verify -triple=x86_64-apple-darwin9
+
+typedef float float4 __attribute__((ext_vector_type(4)));
+typedef int int3 __attribute__((ext_vector_type(3)));
+typedef unsigned unsigned4 __attribute__((ext_vector_type(4)));
+
+struct Foo {
+  char *p;
+};
+
+void test_builtin_reduce_max(int i, float4 v, int3 iv) {
+  struct Foo s = __builtin_reduce_max(iv);
+  // expected-error@-1 {{initializing 'struct Foo' with an expression of incompatible type 'int'}}
+
+  i = __builtin_reduce_max(v, v);
+  // expected-error@-1 {{too many arguments to function call, expected 1, have 2}}
+
+  i = __builtin_reduce_max();
+  // expected-error@-1 {{too few arguments to function call, expected 1, have 0}}
+
+  i = __builtin_reduce_max(i);
+  // expected-error@-1 {{1st argument must be a vector type (was 'int')}}
+}
+
+void test_builtin_reduce_min(int i, float4 v, int3 iv) {
+  struct Foo s = __builtin_reduce_min(iv);
+  // expected-error@-1 {{initializing 'struct Foo' with an expression of incompatible type 'int'}}
+
+  i = __builtin_reduce_min(v, v);
+  // expected-error@-1 {{too many arguments to function call, expected 1, have 2}}
+
+  i = __builtin_reduce_min();
+  // expected-error@-1 {{too few arguments to function call, expected 1, have 0}}
+
+  i = __builtin_reduce_min(i);
+  // expected-error@-1 {{1st argument must be a vector type (was 'int')}}
+}
Index: clang/test/CodeGen/builtins-reduction-math.c
===
--- /dev/null
+++ clang/test/CodeGen/builtins-reduction-math.c
@@ -0,0 +1,59 @@
+// RUN: %clang_cc1 -triple x86_64-apple-darwin %s -emit-llvm -disable-llvm-passes -o - | FileCheck %s
+
+typedef float float4 __attribute__((ext_vector_type(4)));
+typedef short int si8 __attribute__((ext_vector_type(8)));
+typedef unsigned int u4 __attribute__((ext_vector_type(4)));
+
+__attribute__((address_space(1))) float4 vf1_as_one;
+
+void test_builtin_reduce_max(float4 vf1, si8 vi1, u4 vu1) {
+  // CHECK-LABEL: define void @test_builtin_reduce_max(
+  // CHECK:  [[VF1:%.+]] = load <4 x float>, <4 x float>* %vf1.addr, align 16
+  // CHECK-NEXT: call float @llvm.vector.reduce.fmax.v4f32(<4 x float> [[VF1]])
+  float r1 = __builtin_reduce_max(vf1);
+
+  // CHECK:  [[VI1:%.+]] = load <8 x i16>, <8 x i16>* %vi1.addr, align 16
+  // CHECK-NEXT: call i16 @llvm.vector.reduce.smax.v8i16(<8 x i16> [[VI1]])
+  short r2 = __builtin_reduce_max(vi1);
+
+  // CHECK:  [[VU1:%.+]] = load <4 x i32>, <4 x i32>* %vu1.addr, align 16
+  // CHECK-NEXT: call i32 @llvm.vector.reduce.umax.v4i32(<4 x i32> [[VU1]])
+  unsigned r3 = __builtin_reduce_max(vu1);
+
+  // CHECK:  [[VF1_AS1:%.+]] = load <4 x float>, <4 x float> addrspace(1)* @vf1_as_one, align 16
+  // CHECK-NEXT: [[RDX1:%.+]] = call float @llvm.vector.reduce.fmax.v4f32(<4 x float> [[VF1_AS1]])
+  // CHECK-NEXT: fpext float [[RDX1]] to double
+  const double r4 = __builtin_reduce_max(vf1_as_one);
+
+  // CHECK:  [[CVI1:%.+]] = load <8 x i16>, <8 x i16>* %cvi1, align 16
+  // CHECK-NEXT: [[RDX2:%.+]] = call i16 @llvm.vector.reduce.smax.v8i16(<8 x i16> [[CVI1]])
+  // CHECK-NEXT: sext i16 [[RDX2]] to i64
+  const si8 cvi1 = vi1;
+  unsigned long long r5 = __builtin_reduce_max(cvi1);
+}
+
+void test_builtin_reduce_min(float4 vf1, si8 vi1, u4 vu1) {
+  // CHECK-LABEL: define void @test_builtin_reduce_min(
+  // CHECK:  [[VF1:%.+]] = load <4 x float>, <4 x float>* %vf1.addr, align 16
+  // CHECK-NEXT: call float @llvm.vector.reduce.fmin.v4f32(<4 x float> [[VF1]])
+  float r1 = __builtin_reduce_min(vf1);
+
+  // CHECK:  [[VI1:%.+]] = load <8 x i16>, <8 x i16>* %vi1.addr, align 16
+  // CHECK-NEXT: call i16 @llvm.vector.reduce.smin.v8i16(<8 x i16> [[VI1]])
+  short r2 = __builtin_reduce_min(vi1);
+
+  // CHECK:  [[VU1:%.+]] = load <4 x i32>, <4 x i32>* %vu1.addr, align 16
+  // CHECK-NEXT: call i32 @llvm.vector.reduce.umin.v4i32(<4 x i32> [[VU1]])
+  unsigned r3 = __builtin_reduce_min(vu1);
+
+  // CHECK:  [[VF1_AS1:%.+]] = load <4 x float>, <4 x float> addrspace(1)* @vf1_as_one, align 16
+  // CHECK-NEXT: [[RDX1:%.+]] = call float @llvm.vect

[PATCH] D108832: [Builtins] Support ext_vector_type args for __builtin_fminf.

2021-08-27 Thread Florian Hahn via Phabricator via cfe-commits
fhahn created this revision.
fhahn added reviewers: erichkeane, rjmccall, thegameg, anemet.
fhahn requested review of this revision.
Herald added a project: clang.

At the moment, the various math builtins only accept the scalar types
defined by libm.

This patch extends __builtin_fminf to also accept ext_vector_type
arguments that can be converted to an ext_vector_type with float as
element type.

This brings Clang more in line with GCC, which already supports math
builtins with ext_vector_type arguments.

If this direction makes sense, I am planning to also convert a few other
builtins that can be extended to vectors directly, like fmax.

In addition to vector types, it would be also good to support matrix
types as follow up I think.

I tried to make sure the same error messages are emitted for the scalar
variant of __builtin_fminf, but there's a difference for the (vector,
float) variant. I still need to dig into where this is coming from.


Repository:
  rG LLVM Github Monorepo

https://reviews.llvm.org/D108832

Files:
  clang/include/clang/Basic/Builtins.def
  clang/include/clang/Sema/Sema.h
  clang/lib/Sema/SemaChecking.cpp
  clang/test/CodeGen/overloaded-math-builtins.c
  clang/test/Sema/overloaded-math-builtins.c

Index: clang/test/Sema/overloaded-math-builtins.c
===
--- clang/test/Sema/overloaded-math-builtins.c
+++ clang/test/Sema/overloaded-math-builtins.c
@@ -8,7 +8,7 @@
   float r2 = __builtin_fminf(ptr, f);
   // expected-error@-1 {{passing 'int *' to parameter of incompatible type 'float'}}
   float r3 = __builtin_fminf(v, f);
-  // expected-error@-1 {{passing 'float4' (vector of 4 'float' values) to parameter of incompatible type 'float'}}
+  // expected-error@-1 {{initializing 'float' with an expression of incompatible type 'float __attribute__((ext_vector_type(4)))' (vector of 4 'float' values)}}
   float r4 = __builtin_fminf(f, v);
   // expected-error@-1 {{passing 'float4' (vector of 4 'float' values) to parameter of incompatible type 'float'}}
 
Index: clang/test/CodeGen/overloaded-math-builtins.c
===
--- /dev/null
+++ clang/test/CodeGen/overloaded-math-builtins.c
@@ -0,0 +1,16 @@
+// RUN: %clang_cc1 -triple=x86_64-apple-darwin -S -o - -emit-llvm %s | FileCheck %s
+
+typedef float float4 __attribute__((ext_vector_type(4)));
+
+void foo(float f, double d, float4 v) {
+  // CHECK:  call float @llvm.minnum.f32(float {{.*}}, float {{.*}})
+  f = __builtin_fminf(f, f);
+
+  // CHECK:  [[CONV1:%.*]] = fptrunc double {{.*}} to float
+  // CHECK:  [[CONV2:%.*]] = fptrunc double {{.*}} to float
+  // CHECK:  call float @llvm.minnum.f32(float [[CONV1]], float [[CONV2]])
+  f = __builtin_fminf(d, d);
+
+  // CHECK:   call <4 x float> @llvm.minnum.v4f32(<4 x float> {{.*}}, <4 x float> {{.*}})
+  v = __builtin_fminf(v, v);
+};
Index: clang/lib/Sema/SemaChecking.cpp
===
--- clang/lib/Sema/SemaChecking.cpp
+++ clang/lib/Sema/SemaChecking.cpp
@@ -1976,6 +1976,10 @@
 break;
   }
 
+  case Builtin::BI__builtin_fminf:
+return SemaBuiltinOverloadedMathBuiltin(TheCall, TheCallResult,
+Context.FloatTy);
+
   case Builtin::BI__builtin_matrix_transpose:
 return SemaBuiltinMatrixTranspose(TheCall, TheCallResult);
 
@@ -16525,6 +16529,55 @@
  _2, _3, _4));
 }
 
+ExprResult Sema::SemaBuiltinOverloadedMathBuiltin(CallExpr *TheCall,
+  ExprResult CallResult,
+  QualType ElementType) {
+  if (checkArgCount(*this, TheCall, 2))
+return ExprError();
+
+  // Apply default Lvalue conversions and convert the expression to size_t.
+  auto ApplyArgumentConversions = [this](Expr *E, QualType T) {
+ExprResult Res(E);
+AssignConvertType LHSConvTy = CheckSingleAssignmentConstraints(T, Res);
+if (DiagnoseAssignmentResult(LHSConvTy, E->getBeginLoc(), T, E->getType(),
+ E, AA_Passing))
+  return ExprResult(true);
+
+ExprResult Conv = DefaultLvalueConversion(E);
+assert(
+!Conv.isInvalid() &&
+"conversion should be possible according to DiagnoseAssignmentResult");
+
+return tryConvertExprToType(Conv.get(), T);
+  };
+
+  if (auto *VecType = ElementType->getAs())
+ElementType = VecType->getElementType();
+
+  QualType ArgTy = ElementType;
+  if (auto *VecType = TheCall->getArg(0)->getType()->getAs()) {
+ArgTy = Context.getExtVectorType(ElementType, VecType->getNumElements());
+  }
+
+  ExprResult A = ApplyArgumentConversions(TheCall->getArg(0), ArgTy);
+  if (A.isInvalid())
+return A;
+
+  ExprResult B = ApplyArgumentConversions(TheCall->getArg(1), ArgTy);
+  if (B.isInvalid())
+return B;
+
+  TheCall->setType(ArgTy);
+
+  auto *D = TheCall->getCalleeDecl();
+  D->addAttr(ConstAtt

[PATCH] D108832: [Builtins] Support ext_vector_type args for __builtin_fminf.

2021-08-27 Thread Florian Hahn via Phabricator via cfe-commits
fhahn added a comment.

> This brings Clang more in line with GCC, which already supports math builtins 
> with ext_vector_type arguments.

This is unfortunately not correct. When I tried this with GCC the 
`ext_vector_type` attribute was dropped and it fell back to `float`.


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D108832/new/

https://reviews.llvm.org/D108832

___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D108832: [Builtins] Support ext_vector_type args for __builtin_fminf.

2021-08-27 Thread Florian Hahn via Phabricator via cfe-commits
fhahn updated this revision to Diff 369135.
fhahn added a comment.

Updated to remove stray comment.

In D108832#2969512 , @erichkeane 
wrote:

> I think I would want some level of examination/analysis as to whether we want 
> to do this with all of the vector-types, instead of just the 
> `ext_vector_type`.

I think we should extend this to all vector types and matrix types. I only went 
with ext_vector_types to keep things simple initially to make sure the 
direction is acceptable first.


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D108832/new/

https://reviews.llvm.org/D108832

Files:
  clang/include/clang/Basic/Builtins.def
  clang/include/clang/Sema/Sema.h
  clang/lib/Sema/SemaChecking.cpp
  clang/test/CodeGen/overloaded-math-builtins.c
  clang/test/Sema/overloaded-math-builtins.c

Index: clang/test/Sema/overloaded-math-builtins.c
===
--- clang/test/Sema/overloaded-math-builtins.c
+++ clang/test/Sema/overloaded-math-builtins.c
@@ -8,7 +8,7 @@
   float r2 = __builtin_fminf(ptr, f);
   // expected-error@-1 {{passing 'int *' to parameter of incompatible type 'float'}}
   float r3 = __builtin_fminf(v, f);
-  // expected-error@-1 {{passing 'float4' (vector of 4 'float' values) to parameter of incompatible type 'float'}}
+  // expected-error@-1 {{initializing 'float' with an expression of incompatible type 'float __attribute__((ext_vector_type(4)))' (vector of 4 'float' values)}}
   float r4 = __builtin_fminf(f, v);
   // expected-error@-1 {{passing 'float4' (vector of 4 'float' values) to parameter of incompatible type 'float'}}
 
Index: clang/test/CodeGen/overloaded-math-builtins.c
===
--- /dev/null
+++ clang/test/CodeGen/overloaded-math-builtins.c
@@ -0,0 +1,16 @@
+// RUN: %clang_cc1 -triple=x86_64-apple-darwin -S -o - -emit-llvm %s | FileCheck %s
+
+typedef float float4 __attribute__((ext_vector_type(4)));
+
+void foo(float f, double d, float4 v) {
+  // CHECK:  call float @llvm.minnum.f32(float {{.*}}, float {{.*}})
+  f = __builtin_fminf(f, f);
+
+  // CHECK:  [[CONV1:%.*]] = fptrunc double {{.*}} to float
+  // CHECK:  [[CONV2:%.*]] = fptrunc double {{.*}} to float
+  // CHECK:  call float @llvm.minnum.f32(float [[CONV1]], float [[CONV2]])
+  f = __builtin_fminf(d, d);
+
+  // CHECK:   call <4 x float> @llvm.minnum.v4f32(<4 x float> {{.*}}, <4 x float> {{.*}})
+  v = __builtin_fminf(v, v);
+};
Index: clang/lib/Sema/SemaChecking.cpp
===
--- clang/lib/Sema/SemaChecking.cpp
+++ clang/lib/Sema/SemaChecking.cpp
@@ -1976,6 +1976,10 @@
 break;
   }
 
+  case Builtin::BI__builtin_fminf:
+return SemaBuiltinOverloadedMathBuiltin(TheCall, TheCallResult,
+Context.FloatTy);
+
   case Builtin::BI__builtin_matrix_transpose:
 return SemaBuiltinMatrixTranspose(TheCall, TheCallResult);
 
@@ -16525,6 +16529,52 @@
  _2, _3, _4));
 }
 
+ExprResult Sema::SemaBuiltinOverloadedMathBuiltin(CallExpr *TheCall,
+  ExprResult CallResult,
+  QualType ElementType) {
+  if (checkArgCount(*this, TheCall, 2))
+return ExprError();
+
+  // Apply default Lvalue conversions and convert the expression to size_t.
+  auto ApplyArgumentConversions = [this](Expr *E, QualType T) {
+ExprResult Res(E);
+AssignConvertType LHSConvTy = CheckSingleAssignmentConstraints(T, Res);
+if (DiagnoseAssignmentResult(LHSConvTy, E->getBeginLoc(), T, E->getType(),
+ E, AA_Passing))
+  return ExprResult(true);
+
+ExprResult Conv = DefaultLvalueConversion(E);
+assert(
+!Conv.isInvalid() &&
+"conversion should be possible according to DiagnoseAssignmentResult");
+
+return tryConvertExprToType(Conv.get(), T);
+  };
+
+  if (auto *VecType = ElementType->getAs())
+ElementType = VecType->getElementType();
+
+  QualType ArgTy = ElementType;
+  if (auto *VecType = TheCall->getArg(0)->getType()->getAs()) {
+ArgTy = Context.getExtVectorType(ElementType, VecType->getNumElements());
+  }
+
+  ExprResult A = ApplyArgumentConversions(TheCall->getArg(0), ArgTy);
+  if (A.isInvalid())
+return A;
+
+  ExprResult B = ApplyArgumentConversions(TheCall->getArg(1), ArgTy);
+  if (B.isInvalid())
+return B;
+
+  TheCall->setType(ArgTy);
+  auto *D = TheCall->getCalleeDecl();
+  D->addAttr(ConstAttr::CreateImplicit(Context, D->getLocation()));
+  TheCall->setArg(0, A.get());
+  TheCall->setArg(1, B.get());
+  return CallResult;
+}
+
 ExprResult Sema::SemaBuiltinMatrixTranspose(CallExpr *TheCall,
 ExprResult CallResult) {
   if (checkArgCount(*this, TheCall, 1))
Index: clang/include/clang/Sema/Sema.h
===

[PATCH] D108832: [Builtins] Support ext_vector_type args for __builtin_fminf.

2021-08-27 Thread Florian Hahn via Phabricator via cfe-commits
fhahn updated this revision to Diff 369136.
fhahn marked 2 inline comments as done.
fhahn added a comment.

Use ExprError() instead of ExprResult(true).


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D108832/new/

https://reviews.llvm.org/D108832

Files:
  clang/include/clang/Basic/Builtins.def
  clang/include/clang/Sema/Sema.h
  clang/lib/Sema/SemaChecking.cpp
  clang/test/CodeGen/overloaded-math-builtins.c
  clang/test/Sema/overloaded-math-builtins.c

Index: clang/test/Sema/overloaded-math-builtins.c
===
--- clang/test/Sema/overloaded-math-builtins.c
+++ clang/test/Sema/overloaded-math-builtins.c
@@ -8,7 +8,7 @@
   float r2 = __builtin_fminf(ptr, f);
   // expected-error@-1 {{passing 'int *' to parameter of incompatible type 'float'}}
   float r3 = __builtin_fminf(v, f);
-  // expected-error@-1 {{passing 'float4' (vector of 4 'float' values) to parameter of incompatible type 'float'}}
+  // expected-error@-1 {{initializing 'float' with an expression of incompatible type 'float __attribute__((ext_vector_type(4)))' (vector of 4 'float' values)}}
   float r4 = __builtin_fminf(f, v);
   // expected-error@-1 {{passing 'float4' (vector of 4 'float' values) to parameter of incompatible type 'float'}}
 
Index: clang/test/CodeGen/overloaded-math-builtins.c
===
--- /dev/null
+++ clang/test/CodeGen/overloaded-math-builtins.c
@@ -0,0 +1,16 @@
+// RUN: %clang_cc1 -triple=x86_64-apple-darwin -S -o - -emit-llvm %s | FileCheck %s
+
+typedef float float4 __attribute__((ext_vector_type(4)));
+
+void foo(float f, double d, float4 v) {
+  // CHECK:  call float @llvm.minnum.f32(float {{.*}}, float {{.*}})
+  f = __builtin_fminf(f, f);
+
+  // CHECK:  [[CONV1:%.*]] = fptrunc double {{.*}} to float
+  // CHECK:  [[CONV2:%.*]] = fptrunc double {{.*}} to float
+  // CHECK:  call float @llvm.minnum.f32(float [[CONV1]], float [[CONV2]])
+  f = __builtin_fminf(d, d);
+
+  // CHECK:   call <4 x float> @llvm.minnum.v4f32(<4 x float> {{.*}}, <4 x float> {{.*}})
+  v = __builtin_fminf(v, v);
+};
Index: clang/lib/Sema/SemaChecking.cpp
===
--- clang/lib/Sema/SemaChecking.cpp
+++ clang/lib/Sema/SemaChecking.cpp
@@ -1976,6 +1976,10 @@
 break;
   }
 
+  case Builtin::BI__builtin_fminf:
+return SemaBuiltinOverloadedMathBuiltin(TheCall, TheCallResult,
+Context.FloatTy);
+
   case Builtin::BI__builtin_matrix_transpose:
 return SemaBuiltinMatrixTranspose(TheCall, TheCallResult);
 
@@ -16525,6 +16529,52 @@
  _2, _3, _4));
 }
 
+ExprResult Sema::SemaBuiltinOverloadedMathBuiltin(CallExpr *TheCall,
+  ExprResult CallResult,
+  QualType ElementType) {
+  if (checkArgCount(*this, TheCall, 2))
+return ExprError();
+
+  // Apply default Lvalue conversions and convert the expression to size_t.
+  auto ApplyArgumentConversions = [this](Expr *E, QualType T) {
+ExprResult Res(E);
+AssignConvertType LHSConvTy = CheckSingleAssignmentConstraints(T, Res);
+if (DiagnoseAssignmentResult(LHSConvTy, E->getBeginLoc(), T, E->getType(),
+ E, AA_Passing))
+  return ExprError();
+
+ExprResult Conv = DefaultLvalueConversion(E);
+assert(
+!Conv.isInvalid() &&
+"conversion should be possible according to DiagnoseAssignmentResult");
+
+return tryConvertExprToType(Conv.get(), T);
+  };
+
+  if (auto *VecType = ElementType->getAs())
+ElementType = VecType->getElementType();
+
+  QualType ArgTy = ElementType;
+  if (auto *VecType = TheCall->getArg(0)->getType()->getAs()) {
+ArgTy = Context.getExtVectorType(ElementType, VecType->getNumElements());
+  }
+
+  ExprResult A = ApplyArgumentConversions(TheCall->getArg(0), ArgTy);
+  if (A.isInvalid())
+return A;
+
+  ExprResult B = ApplyArgumentConversions(TheCall->getArg(1), ArgTy);
+  if (B.isInvalid())
+return B;
+
+  TheCall->setType(ArgTy);
+  auto *D = TheCall->getCalleeDecl();
+  D->addAttr(ConstAttr::CreateImplicit(Context, D->getLocation()));
+  TheCall->setArg(0, A.get());
+  TheCall->setArg(1, B.get());
+  return CallResult;
+}
+
 ExprResult Sema::SemaBuiltinMatrixTranspose(CallExpr *TheCall,
 ExprResult CallResult) {
   if (checkArgCount(*this, TheCall, 1))
Index: clang/include/clang/Sema/Sema.h
===
--- clang/include/clang/Sema/Sema.h
+++ clang/include/clang/Sema/Sema.h
@@ -12643,6 +12643,10 @@
 
   bool CheckPPCMMAType(QualType Type, SourceLocation TypeLoc);
 
+  ExprResult SemaBuiltinOverloadedMathBuiltin(CallExpr *TheCall,
+  ExprResult CallResult,
+  

[PATCH] D108832: [Builtins] Support ext_vector_type args for __builtin_fminf.

2021-08-27 Thread Florian Hahn via Phabricator via cfe-commits
fhahn added inline comments.



Comment at: clang/lib/Sema/SemaChecking.cpp:16544
+ E, AA_Passing))
+  return ExprResult(true);
+

erichkeane wrote:
> Doing this as ExprResult(true) is absurdly jarring.
Updated, thanks!



Comment at: clang/lib/Sema/SemaChecking.cpp:16554
+
+  if (auto *VecType = ElementType->getAs())
+ElementType = VecType->getElementType();

erichkeane wrote:
> I wonder if this should just deal in `VectorType`, which is the type that 
> intends to emulate the GCC vector types.  My understanding is `ExtVectorType` 
> is for the clang-extended vector types.
I think we should extend this to all vector types and matrix types. I only went 
with ext_vector_types to keep things simple initially to make sure the 
direction is acceptable first.




Comment at: clang/lib/Sema/SemaChecking.cpp:16575
+
+  // Update call argument to use the possibly converted matrix argument.
+  TheCall->setArg(0, A.get());

erichkeane wrote:
> What does this comment come from?  Is this supposed to be a 'FIXME'?  I don't 
> see any other matrix stuff here.
Ah sorry, that was a left-over from where I get the boilerplate code to start 
with. It's removed in the latest version.


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D108832/new/

https://reviews.llvm.org/D108832

___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D109137: [clang] NFC: Remove duplicate DependentSizedMatrixType methods

2021-09-02 Thread Florian Hahn via Phabricator via cfe-commits
fhahn accepted this revision.
fhahn added a comment.
This revision is now accepted and ready to land.

LGTM, thanks!


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D109137/new/

https://reviews.llvm.org/D109137

___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D108832: [Builtins] Support ext_vector_type args for __builtin_fminf.

2021-09-17 Thread Florian Hahn via Phabricator via cfe-commits
fhahn planned changes to this revision.
fhahn added a comment.

In D108832#2969538 , @erichkeane 
wrote:

> Codewise I'm ok, but I don't feel comfortable making the direction decision.  
> I'd like to see some level of 'state of things' on the vector types (like, 
> under what conditions does GCC support this, and under what types??), but 
> even then I'm not sure I'm the right one to approve this.

Thanks! I'm preparing a proposal for cfe-dev at the moment. In addition to 
supporting element wise min/max/round & co I think we should also make sure the 
proposal also allows adding reduction versions in a consistent manner. I don't 
think that would be possible when overloading the existing builtins, so I am 
exploring a different direction at the moment.

Marking as changes planned for now.


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D108832/new/

https://reviews.llvm.org/D108832

___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D102478: [Matrix] Emit assumption that matrix indices are valid.

2021-09-22 Thread Florian Hahn via Phabricator via cfe-commits
fhahn added a comment.

All required changes to make use of this have recently landed or are ready to 
land. So I am going to commit this momentarily.


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D102478/new/

https://reviews.llvm.org/D102478

___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D102478: [Matrix] Emit assumption that matrix indices are valid.

2021-09-22 Thread Florian Hahn via Phabricator via cfe-commits
This revision was landed with ongoing or failed builds.
This revision was automatically updated to reflect the committed changes.
Closed by commit rGea21d688dc0a: [Matrix] Emit assumption that matrix indices 
are valid. (authored by fhahn).

Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D102478/new/

https://reviews.llvm.org/D102478

Files:
  clang/lib/CodeGen/CGExpr.cpp
  clang/lib/CodeGen/CGExprScalar.cpp
  clang/test/CodeGen/matrix-type-operators.c
  clang/test/CodeGenCXX/matrix-type-operators.cpp
  clang/test/CodeGenObjC/matrix-type-operators.m
  llvm/include/llvm/IR/MatrixBuilder.h

Index: llvm/include/llvm/IR/MatrixBuilder.h
===
--- llvm/include/llvm/IR/MatrixBuilder.h
+++ llvm/include/llvm/IR/MatrixBuilder.h
@@ -231,9 +231,23 @@
: (IsUnsigned ? B.CreateUDiv(LHS, RHS) : B.CreateSDiv(LHS, RHS));
   }
 
-  /// Extracts the element at (\p RowIdx, \p ColumnIdx) from \p Matrix.
-  Value *CreateExtractElement(Value *Matrix, Value *RowIdx, Value *ColumnIdx,
-  unsigned NumRows, Twine const &Name = "") {
+  /// Create an assumption that \p Idx is less than \p NumElements.
+  void CreateIndexAssumption(Value *Idx, unsigned NumElements,
+ Twine const &Name = "") {
+
+Value *NumElts =
+B.getIntN(Idx->getType()->getScalarSizeInBits(), NumElements);
+auto *Cmp = B.CreateICmpULT(Idx, NumElts);
+if (auto *ConstCond = dyn_cast(Cmp))
+  assert(ConstCond->isOne() && "Index must be valid!");
+else
+  B.CreateAssumption(Cmp);
+  }
+
+  /// Compute the index to access the element at (\p RowIdx, \p ColumnIdx) from
+  /// a matrix with \p NumRows embedded in a vector.
+  Value *CreateIndex(Value *RowIdx, Value *ColumnIdx, unsigned NumRows,
+ Twine const &Name = "") {
 
 unsigned MaxWidth = std::max(RowIdx->getType()->getScalarSizeInBits(),
  ColumnIdx->getType()->getScalarSizeInBits());
@@ -241,9 +255,7 @@
 RowIdx = B.CreateZExt(RowIdx, IntTy);
 ColumnIdx = B.CreateZExt(ColumnIdx, IntTy);
 Value *NumRowsV = B.getIntN(MaxWidth, NumRows);
-return B.CreateExtractElement(
-Matrix, B.CreateAdd(B.CreateMul(ColumnIdx, NumRowsV), RowIdx),
-"matext");
+return B.CreateAdd(B.CreateMul(ColumnIdx, NumRowsV), RowIdx);
   }
 };
 
Index: clang/test/CodeGenObjC/matrix-type-operators.m
===
--- clang/test/CodeGenObjC/matrix-type-operators.m
+++ clang/test/CodeGenObjC/matrix-type-operators.m
@@ -22,9 +22,9 @@
 // CHECK-NEXT:[[IV2_PTR:%.*]] = bitcast %0* [[IV2]] to i8*
 // CHECK-NEXT:[[CALL1:%.*]] = call i32 bitcast (i8* (i8*, i8*, ...)* @objc_msgSend to i32 (i8*, i8*)*)(i8* [[IV2_PTR]], i8* [[SEL2]])
 // CHECK-NEXT:[[CONV2:%.*]] = sext i32 [[CALL1]] to i64
-// CHECK-NEXT:[[MAT:%.*]] = load <16 x double>, <16 x double>* {{.*}} align 8
 // CHECK-NEXT:[[IDX1:%.*]] = mul i64 [[CONV2]], 4
 // CHECK-NEXT:[[IDX2:%.*]] = add i64 [[IDX1]], [[CONV]]
+// CHECK-NEXT:[[MAT:%.*]] = load <16 x double>, <16 x double>* {{.*}} align 8
 // CHECK-NEXT:[[MATEXT:%.*]] = extractelement <16 x double> [[MAT]], i64 [[IDX2]]
 // CHECK-NEXT:ret double [[MATEXT]]
 //
@@ -49,12 +49,12 @@
 // CHECK-NEXT:[[IV2_PTR:%.*]] = bitcast %0* [[IV2]] to i8*
 // CHECK-NEXT:[[CALL1:%.*]] = call i32 bitcast (i8* (i8*, i8*, ...)* @objc_msgSend to i32 (i8*, i8*)*)(i8* [[IV2_PTR]], i8* [[SEL2]])
 // CHECK-NEXT:[[CONV2:%.*]] = sext i32 [[CALL1]] to i64
+// CHECK-NEXT:[[IDX1:%.*]] = mul i64 [[CONV2]], 4
+// CHECK-NEXT:[[IDX2:%.*]] = add i64 [[IDX1]], [[CONV]]
 // CHECK-NEXT:[[M:%.*]] = load %1*, %1** %m.addr, align 8
 // CHECK-NEXT:[[SEL3:%.*]] = load i8*, i8** @OBJC_SELECTOR_REFERENCES_, align 8, !invariant.load !7
 // CHECK-NEXT:[[M_PTR:%.*]] = bitcast %1* [[M]] to i8*
 // CHECK-NEXT:[[MAT:%.*]] = call <16 x double> bitcast (i8* (i8*, i8*, ...)* @objc_msgSend to <16 x double> (i8*, i8*)*)(i8* [[M_PTR]], i8* [[SEL3]])
-// CHECK-NEXT:[[IDX1:%.*]] = mul i64 [[CONV2]], 4
-// CHECK-NEXT:[[IDX2:%.*]] = add i64 [[IDX1]], [[CONV]]
 // CHECK-NEXT:[[MATEXT:%.*]] = extractelement <16 x double> [[MAT]], i64 [[IDX2]]
 // CHECK-NEXT:ret double [[MATEXT]]
 //
Index: clang/test/CodeGenCXX/matrix-type-operators.cpp
===
--- clang/test/CodeGenCXX/matrix-type-operators.cpp
+++ clang/test/CodeGenCXX/matrix-type-operators.cpp
@@ -1,4 +1,5 @@
-// RUN: %clang_cc1 -fenable-matrix -triple x86_64-apple-darwin %s -emit-llvm -disable-llvm-passes -o - -std=c++11 | FileCheck %s
+// RUN: %clang_cc1 -O0 -fenable-matrix -triple x86_64-apple-darwin %s -emit-llvm -disable-llvm-passes -o - -std=c++11 | FileCheck %s
+// RUN: %clang_cc1 -O1 -fenable-matrix -triple x86_64-apple-darwin %s -emit-llvm -disable-llvm-pas

[PATCH] D32199: [TySan] A Type Sanitizer (Clang)

2023-03-06 Thread Florian Hahn via Phabricator via cfe-commits
fhahn updated this revision to Diff 502607.
fhahn added a comment.

Rebased


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D32199/new/

https://reviews.llvm.org/D32199

Files:
  clang/include/clang/Basic/Features.def
  clang/include/clang/Basic/Sanitizers.def
  clang/include/clang/Driver/SanitizerArgs.h
  clang/lib/CodeGen/BackendUtil.cpp
  clang/lib/CodeGen/CGDecl.cpp
  clang/lib/CodeGen/CGDeclCXX.cpp
  clang/lib/CodeGen/CodeGenFunction.cpp
  clang/lib/CodeGen/CodeGenModule.cpp
  clang/lib/CodeGen/CodeGenTBAA.cpp
  clang/lib/CodeGen/SanitizerMetadata.cpp
  clang/lib/CodeGen/SanitizerMetadata.h
  clang/lib/Driver/SanitizerArgs.cpp
  clang/lib/Driver/ToolChains/CommonArgs.cpp
  clang/lib/Driver/ToolChains/Darwin.cpp
  clang/lib/Driver/ToolChains/Linux.cpp
  clang/test/CodeGen/sanitize-type-attr.cpp
  clang/test/Driver/sanitizer-ld.c

Index: clang/test/Driver/sanitizer-ld.c
===
--- clang/test/Driver/sanitizer-ld.c
+++ clang/test/Driver/sanitizer-ld.c
@@ -268,6 +268,28 @@
 // CHECK-ASAN-MYRIAD-NOT: "-lc"
 // CHECK-ASAN-MYRIAD: libclang_rt.asan-sparcel.a"
 
+// RUN: %clangxx %s -### -o %t.o 2>&1 \
+// RUN: --target=x86_64-unknown-linux -fuse-ld=ld -stdlib=platform -lstdc++ \
+// RUN: -fsanitize=type \
+// RUN: -resource-dir=%S/Inputs/resource_dir \
+// RUN: --sysroot=%S/Inputs/basic_linux_tree \
+// RUN:   | FileCheck --check-prefix=CHECK-TYSAN-LINUX-CXX %s
+//
+// CHECK-TYSAN-LINUX-CXX: "{{(.*[^-.0-9A-Z_a-z])?}}ld{{(.exe)?}}"
+// CHECK-TYSAN-LINUX-CXX-NOT: stdc++
+// CHECK-TYSAN-LINUX-CXX: "--whole-archive" "{{.*}}libclang_rt.tysan{{[^.]*}}.a" "--no-whole-archive"
+// CHECK-TYSAN-LINUX-CXX: stdc++
+
+// RUN: %clangxx -fsanitize=type -### %s 2>&1 \
+// RUN: -mmacosx-version-min=10.6 \
+// RUN: --target=x86_64-apple-darwin13.4.0 -fuse-ld=ld -stdlib=platform \
+// RUN: -resource-dir=%S/Inputs/resource_dir \
+// RUN: --sysroot=%S/Inputs/basic_linux_tree \
+// RUN:   | FileCheck --check-prefix=CHECK-TYSAN-DARWIN-CXX %s
+// CHECK-TYSAN-DARWIN-CXX: "{{.*}}ld{{(.exe)?}}"
+// CHECK-TYSAN-DARWIN-CXX: libclang_rt.tysan_osx_dynamic.dylib
+// CHECK-TYSAN-DARWIN-CXX-NOT: -lc++abi
+
 // RUN: %clangxx -### %s 2>&1 \
 // RUN: --target=x86_64-unknown-linux -fuse-ld=ld -stdlib=platform -lstdc++ \
 // RUN: -fsanitize=thread \
Index: clang/test/CodeGen/sanitize-type-attr.cpp
===
--- /dev/null
+++ clang/test/CodeGen/sanitize-type-attr.cpp
@@ -0,0 +1,74 @@
+// RUN: %clang_cc1 -triple x86_64-linux-gnu -emit-llvm -o - %s | FileCheck -check-prefix=WITHOUT %s
+// RUN: %clang_cc1 -triple x86_64-linux-gnu -emit-llvm -o - %s -fsanitize=type | FileCheck -check-prefix=TYSAN %s
+// RUN: echo "src:%s" | sed -e 's/\\//g' > %t
+// RUN: %clang_cc1 -triple x86_64-linux-gnu -emit-llvm -o - %s -fsanitize=type -fsanitize-blacklist=%t | FileCheck -check-prefix=BL %s
+
+// The sanitize_type attribute should be attached to functions
+// when TypeSanitizer is enabled, unless no_sanitize("type") attribute
+// is present.
+
+// WITHOUT:  NoTYSAN1{{.*}}) [[NOATTR:#[0-9]+]]
+// BL:  NoTYSAN1{{.*}}) [[NOATTR:#[0-9]+]]
+// TYSAN:  NoTYSAN1{{.*}}) [[NOATTR:#[0-9]+]]
+__attribute__((no_sanitize("type"))) int NoTYSAN1(int *a) { return *a; }
+
+// WITHOUT:  NoTYSAN2{{.*}}) [[NOATTR]]
+// BL:  NoTYSAN2{{.*}}) [[NOATTR]]
+// TYSAN:  NoTYSAN2{{.*}}) [[NOATTR]]
+__attribute__((no_sanitize("type"))) int NoTYSAN2(int *a);
+int NoTYSAN2(int *a) { return *a; }
+
+// WITHOUT:  NoTYSAN3{{.*}}) [[NOATTR:#[0-9]+]]
+// BL:  NoTYSAN3{{.*}}) [[NOATTR:#[0-9]+]]
+// TYSAN:  NoTYSAN3{{.*}}) [[NOATTR:#[0-9]+]]
+__attribute__((no_sanitize("type"))) int NoTYSAN3(int *a) { return *a; }
+
+// WITHOUT:  TYSANOk{{.*}}) [[NOATTR]]
+// BL:  TYSANOk{{.*}}) [[NOATTR]]
+// TYSAN: TYSANOk{{.*}}) [[WITH:#[0-9]+]]
+int TYSANOk(int *a) { return *a; }
+
+// WITHOUT:  TemplateTYSANOk{{.*}}) [[NOATTR]]
+// BL:  TemplateTYSANOk{{.*}}) [[NOATTR]]
+// TYSAN: TemplateTYSANOk{{.*}}) [[WITH]]
+template 
+int TemplateTYSANOk() { return i; }
+
+// WITHOUT:  TemplateNoTYSAN{{.*}}) [[NOATTR]]
+// BL:  TemplateNoTYSAN{{.*}}) [[NOATTR]]
+// TYSAN: TemplateNoTYSAN{{.*}}) [[NOATTR]]
+template 
+__attribute__((no_sanitize("type"))) int TemplateNoTYSAN() { return i; }
+
+int force_instance = TemplateTYSANOk<42>() + TemplateNoTYSAN<42>();
+
+// Check that __cxx_global_var_init* get the sanitize_type attribute.
+int global1 = 0;
+int global2 = *(int *)((char *)&global1 + 1);
+// WITHOUT: @__cxx_global_var_init{{.*}}[[NOATTR:#[0-9]+]]
+// BL: @__cxx_global_var_init{{.*}}[[NOATTR:#[0-9]+]]
+// TYSAN: @__cxx_global_var_init{{.*}}[[WITH:#[0-9]+]]
+
+// Make sure that we don't add globals to the list for which we don't have a
+// specific type description.
+// FIXME: We now have a type description for this type and a global is added. Should it?
+struct SX {
+  int a, b;
+};
+SX sx;
+
+// WITHOUT: attributes

[PATCH] D145151: clang: Handle MatrixType in hasFloatingRepresentation

2023-03-07 Thread Florian Hahn via Phabricator via cfe-commits
fhahn accepted this revision.
fhahn added a comment.
This revision is now accepted and ready to land.

LGTM, thanks!


CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D145151/new/

https://reviews.llvm.org/D145151

___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D145270: Add codegen for llvm exp/exp2 elementwise builtins

2023-03-08 Thread Florian Hahn via Phabricator via cfe-commits
fhahn added inline comments.



Comment at: clang/docs/LanguageExtensions.rst:643
+ T __builtin_elementwise_exp(T x)returns the base-e exponential, 
or e^x, of the specified value   floating point types
+ T __builtin_elementwise_exp2(T x)   returns the base-2 exponential, 
or 2^x, of the specified value   floating point types
  T __builtin_elementwise_roundeven(T x)  round x to the nearest integer 
value in floating point format,   floating point types

the wording using `or` seems a bit confusing as it might be interpreted as 
either-or (but I am not a native speaker). It might be slightly better to 
perhaps just drop the `or`?


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D145270/new/

https://reviews.llvm.org/D145270

___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D145270: Add codegen for llvm exp/exp2 elementwise builtins

2023-03-09 Thread Florian Hahn via Phabricator via cfe-commits
fhahn accepted this revision.
fhahn added a comment.
This revision is now accepted and ready to land.

LGTM, thanks!


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D145270/new/

https://reviews.llvm.org/D145270

___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D148944: [clang][Driver] Fix crash with unsupported architectures in MinGW and CrossWindows.

2023-04-28 Thread Florian Hahn via Phabricator via cfe-commits
fhahn resigned from this revision.
fhahn added a comment.

Sorry, I am not familiar at all with this code. Perhaps @shafik could suggest 
more appropriate reviewers


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D148944/new/

https://reviews.llvm.org/D148944

___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D149006: [llvm][Support] Replace `%` operator with `&` in `Align::isAligned(...)`

2023-04-28 Thread Florian Hahn via Phabricator via cfe-commits
fhahn added a comment.

> it is easier to check reminder by conjunction with mask, which is (Pow2Value 
> - 1).

Hmm, easier in what respect? Isn't the original code more straight-forward?


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D149006/new/

https://reviews.llvm.org/D149006

___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D148381: [WIP][Clang] Add element_count attribute

2023-05-12 Thread Florian Hahn via Phabricator via cfe-commits
fhahn added reviewers: rapidsna, fcloutier.
fhahn added a comment.

Adding a few people who have been working on `-fbounds-safety` proposal 
(https://llvm.swoogo.com/2023eurollvm/session/1414468/keynote-“-fbounds-safety”-enforcing-bounds-safety-for-production-c-code)


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D148381/new/

https://reviews.llvm.org/D148381

___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D142934: clang: Use ptrmask for pointer alignment

2023-02-28 Thread Florian Hahn via Phabricator via cfe-commits
fhahn accepted this revision.
fhahn added a comment.
This revision is now accepted and ready to land.

LGTM, thanks!

> The __builtin_align_{up,down} code generation could also make use of this 
> IIRC. I think the reason I didn't do this initially was concerns about 
> ptrmask not being optimized as well.

Yeah, I think it would probably be good to use the intrinsic and just address 
the remaining relevant gaps, if there are any.


CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D142934/new/

https://reviews.llvm.org/D142934

___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D151076: [IRGen] Handle infinite cycles in findDominatingStoreToReturnValue.

2023-05-22 Thread Florian Hahn via Phabricator via cfe-commits
fhahn created this revision.
fhahn added reviewers: rjmccall, aaron.ballman, efriedma.
Herald added a subscriber: StephenFan.
Herald added a project: All.
fhahn requested review of this revision.
Herald added a project: clang.
Herald added a subscriber: cfe-commits.

If there is an infinite cycle in the IR, the loop will never exit. Keep
track of visited basic blocks in a set and return nullptr if a block is
visited again.

Fixes #62830.


Repository:
  rG LLVM Github Monorepo

https://reviews.llvm.org/D151076

Files:
  clang/lib/CodeGen/CGCall.cpp
  clang/test/CodeGen/dominating-store-infinite-cycle.c


Index: clang/test/CodeGen/dominating-store-infinite-cycle.c
===
--- /dev/null
+++ clang/test/CodeGen/dominating-store-infinite-cycle.c
@@ -0,0 +1,33 @@
+// NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py 
UTC_ARGS: --version 2
+// RUN: %clang_cc1 -triple x86_64-unknown-linux-gnu -S -emit-llvm %s -o - | 
FileCheck %s
+
+// Test for PR62830 where there are 2 infinite cycles using goto. Make sure
+// clang codegen doesn't hang.
+int a;
+
+// CHECK-LABEL: define dso_local i32 @main
+// CHECK-SAME: () #[[ATTR0:[0-9]+]] {
+// CHECK-NEXT:  entry:
+// CHECK-NEXT:[[RETVAL:%.*]] = alloca i32, align 4
+// CHECK-NEXT:store i32 0, ptr [[RETVAL]], align 4
+// CHECK-NEXT:br label [[L1:%.*]]
+// CHECK:   L1:
+// CHECK-NEXT:br label [[L1]]
+// CHECK:   L2:
+// CHECK-NEXT:[[TMP0:%.*]] = load i32, ptr @a, align 4
+// CHECK-NEXT:[[TOBOOL:%.*]] = icmp ne i32 [[TMP0]], 0
+// CHECK-NEXT:br i1 [[TOBOOL]], label [[IF_END:%.*]], label [[IF_THEN:%.*]]
+// CHECK:   if.then:
+// CHECK-NEXT:br label [[L2:%.*]]
+// CHECK:   if.end:
+// CHECK-NEXT:[[TMP1:%.*]] = load i32, ptr [[RETVAL]], align 4
+// CHECK-NEXT:ret i32 [[TMP1]]
+//
+int main() {
+L1:
+  goto L1;
+
+L2:
+  if (!a)
+goto L2;
+}
Index: clang/lib/CodeGen/CGCall.cpp
===
--- clang/lib/CodeGen/CGCall.cpp
+++ clang/lib/CodeGen/CGCall.cpp
@@ -3461,8 +3461,9 @@
   // single-predecessors chain from the current insertion point.
   llvm::BasicBlock *StoreBB = store->getParent();
   llvm::BasicBlock *IP = CGF.Builder.GetInsertBlock();
+  llvm::SmallPtrSet SeenBBs;
   while (IP != StoreBB) {
-if (!(IP = IP->getSinglePredecessor()))
+if (!SeenBBs.insert(IP).second || !(IP = IP->getSinglePredecessor()))
   return nullptr;
   }
 


Index: clang/test/CodeGen/dominating-store-infinite-cycle.c
===
--- /dev/null
+++ clang/test/CodeGen/dominating-store-infinite-cycle.c
@@ -0,0 +1,33 @@
+// NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py UTC_ARGS: --version 2
+// RUN: %clang_cc1 -triple x86_64-unknown-linux-gnu -S -emit-llvm %s -o - | FileCheck %s
+
+// Test for PR62830 where there are 2 infinite cycles using goto. Make sure
+// clang codegen doesn't hang.
+int a;
+
+// CHECK-LABEL: define dso_local i32 @main
+// CHECK-SAME: () #[[ATTR0:[0-9]+]] {
+// CHECK-NEXT:  entry:
+// CHECK-NEXT:[[RETVAL:%.*]] = alloca i32, align 4
+// CHECK-NEXT:store i32 0, ptr [[RETVAL]], align 4
+// CHECK-NEXT:br label [[L1:%.*]]
+// CHECK:   L1:
+// CHECK-NEXT:br label [[L1]]
+// CHECK:   L2:
+// CHECK-NEXT:[[TMP0:%.*]] = load i32, ptr @a, align 4
+// CHECK-NEXT:[[TOBOOL:%.*]] = icmp ne i32 [[TMP0]], 0
+// CHECK-NEXT:br i1 [[TOBOOL]], label [[IF_END:%.*]], label [[IF_THEN:%.*]]
+// CHECK:   if.then:
+// CHECK-NEXT:br label [[L2:%.*]]
+// CHECK:   if.end:
+// CHECK-NEXT:[[TMP1:%.*]] = load i32, ptr [[RETVAL]], align 4
+// CHECK-NEXT:ret i32 [[TMP1]]
+//
+int main() {
+L1:
+  goto L1;
+
+L2:
+  if (!a)
+goto L2;
+}
Index: clang/lib/CodeGen/CGCall.cpp
===
--- clang/lib/CodeGen/CGCall.cpp
+++ clang/lib/CodeGen/CGCall.cpp
@@ -3461,8 +3461,9 @@
   // single-predecessors chain from the current insertion point.
   llvm::BasicBlock *StoreBB = store->getParent();
   llvm::BasicBlock *IP = CGF.Builder.GetInsertBlock();
+  llvm::SmallPtrSet SeenBBs;
   while (IP != StoreBB) {
-if (!(IP = IP->getSinglePredecessor()))
+if (!SeenBBs.insert(IP).second || !(IP = IP->getSinglePredecessor()))
   return nullptr;
   }
 
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D151061: [test] Add ext_vector_type tests for C

2023-05-22 Thread Florian Hahn via Phabricator via cfe-commits
fhahn added a comment.

Thanks for texting the test coverage!




Comment at: clang/test/Sema/ext_vector_ops.c:30
+void test_int_vector_scalar(unsigned int ua, v2u v2ua) {
+  // Integer vector vs integer operators. These will splat
+  (void)(v2ua + ua);

Not sure if `vs` is the right connector here, maybe something like `Operators 
with one integer vector and scalar.`. Period at end of `These will splat`


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D151061/new/

https://reviews.llvm.org/D151061

___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D146987: [Assignment Tracking] Enable by default

2023-05-22 Thread Florian Hahn via Phabricator via cfe-commits
fhahn added a comment.

Looks like this is causing a crash on current `main`: 
https://github.com/llvm/llvm-project/issues/62838

Please take a look and revert the commit if it requires longer to fix.


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D146987/new/

https://reviews.llvm.org/D146987

___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D151061: [test] Add ext_vector_type tests for C

2023-05-22 Thread Florian Hahn via Phabricator via cfe-commits
fhahn accepted this revision.
fhahn added a comment.
This revision is now accepted and ready to land.

LGTM, thanks!


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D151061/new/

https://reviews.llvm.org/D151061

___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


<    2   3   4   5   6   7   8   >