[PATCH] D148422: [ClangFE] Handle statement expressions properly with CheckAtomicAlignment()

2023-04-18 Thread Jonas Paulsson 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 rG790c9ac529c9: [ClangFE] Handle statement expressions 
properly with CheckAtomicAlignment(). (authored by jonpa).
Herald added a project: clang.
Herald added a subscriber: cfe-commits.

Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D148422

Files:
  clang/lib/CodeGen/CGBuiltin.cpp
  clang/test/CodeGen/SystemZ/sync-builtins-i128-16Al.c

Index: clang/test/CodeGen/SystemZ/sync-builtins-i128-16Al.c
===
--- clang/test/CodeGen/SystemZ/sync-builtins-i128-16Al.c
+++ clang/test/CodeGen/SystemZ/sync-builtins-i128-16Al.c
@@ -204,3 +204,16 @@
 __int128 f17() {
   return __sync_swap(, Val);
 }
+
+// Test that a statement expression compiles.
+// CHECK-LABEL: @f18(
+// CHECK-NEXT:  entry:
+// CHECK-NEXT:[[T_ADDR:%.*]] = alloca i128, align 8
+// CHECK-NEXT:[[T:%.*]] = load i128, ptr [[TMP0:%.*]], align 8, !tbaa [[TBAA2]]
+// CHECK-NEXT:store i128 [[T]], ptr [[T_ADDR]], align 8, !tbaa [[TBAA2]]
+// CHECK-NEXT:[[TMP1:%.*]] = cmpxchg ptr [[T_ADDR]], i128 [[T]], i128 [[T]] seq_cst seq_cst, align 16
+// CHECK-NEXT:ret void
+//
+void f18(__int128 t) {
+  __sync_bool_compare_and_swap(({int x = 1; }), t, t);
+}
Index: clang/lib/CodeGen/CGBuiltin.cpp
===
--- clang/lib/CodeGen/CGBuiltin.cpp
+++ clang/lib/CodeGen/CGBuiltin.cpp
@@ -170,6 +170,21 @@
   return V;
 }
 
+static llvm::Value *CheckAtomicAlignment(CodeGenFunction ,
+ const CallExpr *E) {
+  ASTContext  = CGF.getContext();
+  Address Ptr = CGF.EmitPointerWithAlignment(E->getArg(0));
+  unsigned Bytes = Ptr.getElementType()->isPointerTy()
+   ? Ctx.getTypeSizeInChars(Ctx.VoidPtrTy).getQuantity()
+   : Ptr.getElementType()->getScalarSizeInBits() / 8;
+  unsigned Align = Ptr.getAlignment().getQuantity();
+  if (Align % Bytes != 0) {
+DiagnosticsEngine  = CGF.CGM.getDiags();
+Diags.Report(E->getBeginLoc(), diag::warn_sync_op_misaligned);
+  }
+  return Ptr.getPointer();
+}
+
 /// Utility to insert an atomic instruction based on Intrinsic::ID
 /// and the expression node.
 static Value *MakeBinaryAtomicValue(
@@ -182,7 +197,7 @@
   E->getArg(0)->getType()->getPointeeType()));
   assert(CGF.getContext().hasSameUnqualifiedType(T, E->getArg(1)->getType()));
 
-  llvm::Value *DestPtr = CGF.EmitScalarExpr(E->getArg(0));
+  llvm::Value *DestPtr = CheckAtomicAlignment(CGF, E);
   unsigned AddrSpace = DestPtr->getType()->getPointerAddressSpace();
 
   llvm::IntegerType *IntType =
@@ -224,23 +239,9 @@
   return CGF.EmitLoadOfScalar(LV, E->getExprLoc());
 }
 
-static void CheckAtomicAlignment(CodeGenFunction , const CallExpr *E) {
-  ASTContext  = CGF.getContext();
-  Address Ptr = CGF.EmitPointerWithAlignment(E->getArg(0));
-  unsigned Bytes = Ptr.getElementType()->isPointerTy()
-   ? Ctx.getTypeSizeInChars(Ctx.VoidPtrTy).getQuantity()
-   : Ptr.getElementType()->getScalarSizeInBits() / 8;
-  unsigned Align = Ptr.getAlignment().getQuantity();
-  if (Align % Bytes != 0) {
-DiagnosticsEngine  = CGF.CGM.getDiags();
-Diags.Report(E->getBeginLoc(), diag::warn_sync_op_misaligned);
-  }
-}
-
 static RValue EmitBinaryAtomic(CodeGenFunction ,
llvm::AtomicRMWInst::BinOp Kind,
const CallExpr *E) {
-  CheckAtomicAlignment(CGF, E);
   return RValue::get(MakeBinaryAtomicValue(CGF, Kind, E));
 }
 
@@ -252,14 +253,13 @@
const CallExpr *E,
Instruction::BinaryOps Op,
bool Invert = false) {
-  CheckAtomicAlignment(CGF, E);
   QualType T = E->getType();
   assert(E->getArg(0)->getType()->isPointerType());
   assert(CGF.getContext().hasSameUnqualifiedType(T,
   E->getArg(0)->getType()->getPointeeType()));
   assert(CGF.getContext().hasSameUnqualifiedType(T, E->getArg(1)->getType()));
 
-  llvm::Value *DestPtr = CGF.EmitScalarExpr(E->getArg(0));
+  llvm::Value *DestPtr = CheckAtomicAlignment(CGF, E);
   unsigned AddrSpace = DestPtr->getType()->getPointerAddressSpace();
 
   llvm::IntegerType *IntType =
@@ -300,9 +300,8 @@
 /// invoke the function EmitAtomicCmpXchgForMSIntrin.
 static Value *MakeAtomicCmpXchgValue(CodeGenFunction , const CallExpr *E,
  bool ReturnBool) {
-  CheckAtomicAlignment(CGF, E);
   QualType T = ReturnBool ? E->getArg(1)->getType() : E->getType();
-  llvm::Value *DestPtr = CGF.EmitScalarExpr(E->getArg(0));
+  llvm::Value *DestPtr = CheckAtomicAlignment(CGF, E);
   unsigned AddrSpace = 

[PATCH] D143813: [ClangFE] Check that __sync builtins are naturally aligned.

2023-04-15 Thread Jonas Paulsson via Phabricator via cfe-commits
jonpa accepted this revision.
jonpa added a comment.
This revision is now accepted and ready to land.

In D143813#4269073 , @efriedma wrote:

> Please don't upload reviews for followup patches on top of the original 
> patch; it confuses the history of happened when.  But sure, looks fine.

Sorry - moved this last follow-up diff to https://reviews.llvm.org/D148422.


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

https://reviews.llvm.org/D143813

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


[PATCH] D143813: [ClangFE] Check that __sync builtins are naturally aligned.

2023-04-14 Thread Jonas Paulsson via Phabricator via cfe-commits
jonpa updated this revision to Diff 513573.
jonpa added a comment.

> Should be straightforward to fix, though; just make CheckAtomicAlignment 
> return the computed pointer.

Something like this?


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

https://reviews.llvm.org/D143813

Files:
  clang/lib/CodeGen/CGBuiltin.cpp
  clang/test/CodeGen/SystemZ/sync-builtins-i128-16Al.c

Index: clang/test/CodeGen/SystemZ/sync-builtins-i128-16Al.c
===
--- clang/test/CodeGen/SystemZ/sync-builtins-i128-16Al.c
+++ clang/test/CodeGen/SystemZ/sync-builtins-i128-16Al.c
@@ -204,3 +204,16 @@
 __int128 f17() {
   return __sync_swap(, Val);
 }
+
+// Test that a statement expression compiles.
+// CHECK-LABEL: @f18(
+// CHECK-NEXT:  entry:
+// CHECK-NEXT:[[T_ADDR:%.*]] = alloca i128, align 8
+// CHECK-NEXT:[[T:%.*]] = load i128, ptr [[TMP0:%.*]], align 8, !tbaa [[TBAA2]]
+// CHECK-NEXT:store i128 [[T]], ptr [[T_ADDR]], align 8, !tbaa [[TBAA2]]
+// CHECK-NEXT:[[TMP1:%.*]] = cmpxchg ptr [[T_ADDR]], i128 [[T]], i128 [[T]] seq_cst seq_cst, align 16
+// CHECK-NEXT:ret void
+//
+void f18(__int128 t) {
+  __sync_bool_compare_and_swap(({int x = 1; }), t, t);
+}
Index: clang/lib/CodeGen/CGBuiltin.cpp
===
--- clang/lib/CodeGen/CGBuiltin.cpp
+++ clang/lib/CodeGen/CGBuiltin.cpp
@@ -170,6 +170,21 @@
   return V;
 }
 
+static llvm::Value *CheckAtomicAlignment(CodeGenFunction ,
+ const CallExpr *E) {
+  ASTContext  = CGF.getContext();
+  Address Ptr = CGF.EmitPointerWithAlignment(E->getArg(0));
+  unsigned Bytes = Ptr.getElementType()->isPointerTy()
+   ? Ctx.getTypeSizeInChars(Ctx.VoidPtrTy).getQuantity()
+   : Ptr.getElementType()->getScalarSizeInBits() / 8;
+  unsigned Align = Ptr.getAlignment().getQuantity();
+  if (Align % Bytes != 0) {
+DiagnosticsEngine  = CGF.CGM.getDiags();
+Diags.Report(E->getBeginLoc(), diag::warn_sync_op_misaligned);
+  }
+  return Ptr.getPointer();
+}
+
 /// Utility to insert an atomic instruction based on Intrinsic::ID
 /// and the expression node.
 static Value *MakeBinaryAtomicValue(
@@ -182,7 +197,7 @@
   E->getArg(0)->getType()->getPointeeType()));
   assert(CGF.getContext().hasSameUnqualifiedType(T, E->getArg(1)->getType()));
 
-  llvm::Value *DestPtr = CGF.EmitScalarExpr(E->getArg(0));
+  llvm::Value *DestPtr = CheckAtomicAlignment(CGF, E);
   unsigned AddrSpace = DestPtr->getType()->getPointerAddressSpace();
 
   llvm::IntegerType *IntType =
@@ -224,23 +239,9 @@
   return CGF.EmitLoadOfScalar(LV, E->getExprLoc());
 }
 
-static void CheckAtomicAlignment(CodeGenFunction , const CallExpr *E) {
-  ASTContext  = CGF.getContext();
-  Address Ptr = CGF.EmitPointerWithAlignment(E->getArg(0));
-  unsigned Bytes = Ptr.getElementType()->isPointerTy()
-   ? Ctx.getTypeSizeInChars(Ctx.VoidPtrTy).getQuantity()
-   : Ptr.getElementType()->getScalarSizeInBits() / 8;
-  unsigned Align = Ptr.getAlignment().getQuantity();
-  if (Align % Bytes != 0) {
-DiagnosticsEngine  = CGF.CGM.getDiags();
-Diags.Report(E->getBeginLoc(), diag::warn_sync_op_misaligned);
-  }
-}
-
 static RValue EmitBinaryAtomic(CodeGenFunction ,
llvm::AtomicRMWInst::BinOp Kind,
const CallExpr *E) {
-  CheckAtomicAlignment(CGF, E);
   return RValue::get(MakeBinaryAtomicValue(CGF, Kind, E));
 }
 
@@ -252,14 +253,13 @@
const CallExpr *E,
Instruction::BinaryOps Op,
bool Invert = false) {
-  CheckAtomicAlignment(CGF, E);
   QualType T = E->getType();
   assert(E->getArg(0)->getType()->isPointerType());
   assert(CGF.getContext().hasSameUnqualifiedType(T,
   E->getArg(0)->getType()->getPointeeType()));
   assert(CGF.getContext().hasSameUnqualifiedType(T, E->getArg(1)->getType()));
 
-  llvm::Value *DestPtr = CGF.EmitScalarExpr(E->getArg(0));
+  llvm::Value *DestPtr = CheckAtomicAlignment(CGF, E);
   unsigned AddrSpace = DestPtr->getType()->getPointerAddressSpace();
 
   llvm::IntegerType *IntType =
@@ -300,9 +300,8 @@
 /// invoke the function EmitAtomicCmpXchgForMSIntrin.
 static Value *MakeAtomicCmpXchgValue(CodeGenFunction , const CallExpr *E,
  bool ReturnBool) {
-  CheckAtomicAlignment(CGF, E);
   QualType T = ReturnBool ? E->getArg(1)->getType() : E->getType();
-  llvm::Value *DestPtr = CGF.EmitScalarExpr(E->getArg(0));
+  llvm::Value *DestPtr = CheckAtomicAlignment(CGF, E);
   unsigned AddrSpace = DestPtr->getType()->getPointerAddressSpace();
 
   llvm::IntegerType *IntType = llvm::IntegerType::get(
@@ -4045,8 +4044,7 @@
   case Builtin::BI__sync_lock_release_4:
   case 

[PATCH] D143813: [ClangFE] Check that __sync builtins are naturally aligned.

2023-04-14 Thread Jonas Paulsson via Phabricator via cfe-commits
jonpa added a comment.

In D143813#4258744 , @ahatanak wrote:

> In D143813#4257943 , @jonpa wrote:
>
>> I don't understand the first argument - I thought it was supposed to be just 
>> an address...
>
> It's a statement expression. 
> https://gcc.gnu.org/onlinedocs/gcc/Statement-Exprs.html
>
> The value of the last subexpression serves as the value of the entire 
> construct.

Ah, ok, thanks!


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D143813

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


[PATCH] D78644: [LSan] Enable for SystemZ

2023-04-14 Thread Jonas Paulsson via Phabricator via cfe-commits
jonpa added a comment.

Update clang/docs/LeakSanitizer.rst (Supported Platforms).


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D78644

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


[PATCH] D143813: [ClangFE] Check that __sync builtins are naturally aligned.

2023-04-11 Thread Jonas Paulsson via Phabricator via cfe-commits
jonpa added a comment.

In D143813#4256969 , @ahatanak wrote:

> I think this patch is causing the assertion in 
> `CodeGenFunction::setAddrOfLocalVar` to fail when the following code is 
> compiled:
>
>   void foo(unsigned long long t) {
> __sync_bool_compare_and_swap(({int x = 1; }), t, t);
>   }
>
> Could you take a look?

I don't understand the first argument - I thought it was supposed to be just an 
address...

This patch seems to (in CheckAtomicAlignment()) call 
CGF.EmitPointerWithAlignment() on the CompoundStmt, which is unexpected. If 
this is a legal parameter for the address, I guess there should be some kind of 
special handling here. Perhaps it would be ok to only emit the warning for 
plain address paramters, I might think...?


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D143813

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


[PATCH] D143813: [ClangFE] Check that __sync builtins are naturally aligned.

2023-03-15 Thread Jonas Paulsson via Phabricator via cfe-commits
This revision was automatically updated to reflect the committed changes.
Closed by commit rG7501e53b8d6d: [Clang] Give warning for an underaligned 
128-bit __sync library call. (authored by jonpa).
Herald added a project: clang.
Herald added a subscriber: cfe-commits.

Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D143813

Files:
  clang/include/clang/Basic/DiagnosticFrontendKinds.td
  clang/include/clang/Basic/DiagnosticGroups.td
  clang/lib/CodeGen/CGBuiltin.cpp
  clang/test/CodeGen/SystemZ/sync-builtins-i128-16Al.c
  clang/test/CodeGen/SystemZ/sync-builtins-i128-8Al.c

Index: clang/test/CodeGen/SystemZ/sync-builtins-i128-8Al.c
===
--- /dev/null
+++ clang/test/CodeGen/SystemZ/sync-builtins-i128-8Al.c
@@ -0,0 +1,27 @@
+// RUN: %clang_cc1 -triple s390x-linux-gnu -O1 -emit-llvm %s -o - 2>&1 | FileCheck %s
+//
+// Test that an underaligned 16 byte __sync gives a warning.
+
+#include 
+
+__int128 Ptr __attribute__((aligned(8)));
+
+__int128 f1() {
+// CHECK: warning: __sync builtin operation MUST have natural alignment (consider using __atomic). [-Wsync-alignment]
+  return __sync_fetch_and_add(, 1);
+}
+
+__int128 f2() {
+// CHECK: warning: __sync builtin operation MUST have natural alignment (consider using __atomic). [-Wsync-alignment]
+  return __sync_sub_and_fetch(, 1);
+}
+
+__int128 f3() {
+// CHECK: warning: __sync builtin operation MUST have natural alignment (consider using __atomic). [-Wsync-alignment]
+  return __sync_val_compare_and_swap(, 0, 1);
+}
+
+void f4() {
+// CHECK: warning: __sync builtin operation MUST have natural alignment (consider using __atomic). [-Wsync-alignment]
+  __sync_lock_release();
+}
Index: clang/test/CodeGen/SystemZ/sync-builtins-i128-16Al.c
===
--- /dev/null
+++ clang/test/CodeGen/SystemZ/sync-builtins-i128-16Al.c
@@ -0,0 +1,206 @@
+// NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py
+// RUN: %clang_cc1 -triple s390x-linux-gnu -O1 -emit-llvm %s -o - \
+// RUN:   | FileCheck %s
+//
+// Test __sync_ builtins for __int128 aligned to 16 bytes.
+
+#include 
+
+__int128 Ptr __attribute__((aligned(16)));
+__int128 Val __attribute__((aligned(16)));
+__int128 OldVal __attribute__((aligned(16)));
+
+// CHECK-LABEL: @f1(
+// CHECK-NEXT:  entry:
+// CHECK-NEXT:[[TMP0:%.*]] = load i128, ptr @Val, align 16, !tbaa [[TBAA2:![0-9]+]]
+// CHECK-NEXT:[[TMP1:%.*]] = atomicrmw add ptr @Ptr, i128 [[TMP0]] seq_cst, align 16
+// CHECK-NEXT:store i128 [[TMP1]], ptr [[AGG_RESULT:%.*]], align 8, !tbaa [[TBAA2]]
+// CHECK-NEXT:ret void
+//
+__int128 f1() {
+  return __sync_fetch_and_add(, Val);
+}
+
+// CHECK-LABEL: @f2(
+// CHECK-NEXT:  entry:
+// CHECK-NEXT:[[TMP0:%.*]] = load i128, ptr @Val, align 16, !tbaa [[TBAA2]]
+// CHECK-NEXT:[[TMP1:%.*]] = atomicrmw sub ptr @Ptr, i128 [[TMP0]] seq_cst, align 16
+// CHECK-NEXT:store i128 [[TMP1]], ptr [[AGG_RESULT:%.*]], align 8, !tbaa [[TBAA2]]
+// CHECK-NEXT:ret void
+//
+__int128 f2() {
+  return __sync_fetch_and_sub(, Val);
+}
+
+// CHECK-LABEL: @f3(
+// CHECK-NEXT:  entry:
+// CHECK-NEXT:[[TMP0:%.*]] = load i128, ptr @Val, align 16, !tbaa [[TBAA2]]
+// CHECK-NEXT:[[TMP1:%.*]] = atomicrmw or ptr @Ptr, i128 [[TMP0]] seq_cst, align 16
+// CHECK-NEXT:store i128 [[TMP1]], ptr [[AGG_RESULT:%.*]], align 8, !tbaa [[TBAA2]]
+// CHECK-NEXT:ret void
+//
+__int128 f3() {
+  return __sync_fetch_and_or(, Val);
+}
+
+// CHECK-LABEL: @f4(
+// CHECK-NEXT:  entry:
+// CHECK-NEXT:[[TMP0:%.*]] = load i128, ptr @Val, align 16, !tbaa [[TBAA2]]
+// CHECK-NEXT:[[TMP1:%.*]] = atomicrmw and ptr @Ptr, i128 [[TMP0]] seq_cst, align 16
+// CHECK-NEXT:store i128 [[TMP1]], ptr [[AGG_RESULT:%.*]], align 8, !tbaa [[TBAA2]]
+// CHECK-NEXT:ret void
+//
+__int128 f4() {
+  return __sync_fetch_and_and(, Val);
+}
+
+// CHECK-LABEL: @f5(
+// CHECK-NEXT:  entry:
+// CHECK-NEXT:[[TMP0:%.*]] = load i128, ptr @Val, align 16, !tbaa [[TBAA2]]
+// CHECK-NEXT:[[TMP1:%.*]] = atomicrmw xor ptr @Ptr, i128 [[TMP0]] seq_cst, align 16
+// CHECK-NEXT:store i128 [[TMP1]], ptr [[AGG_RESULT:%.*]], align 8, !tbaa [[TBAA2]]
+// CHECK-NEXT:ret void
+//
+__int128 f5() {
+  return __sync_fetch_and_xor(, Val);
+}
+
+// CHECK-LABEL: @f6(
+// CHECK-NEXT:  entry:
+// CHECK-NEXT:[[TMP0:%.*]] = load i128, ptr @Val, align 16, !tbaa [[TBAA2]]
+// CHECK-NEXT:[[TMP1:%.*]] = atomicrmw nand ptr @Ptr, i128 [[TMP0]] seq_cst, align 16
+// CHECK-NEXT:store i128 [[TMP1]], ptr [[AGG_RESULT:%.*]], align 8, !tbaa [[TBAA2]]
+// CHECK-NEXT:ret void
+//
+__int128 f6() {
+  return __sync_fetch_and_nand(, Val);
+}
+
+// CHECK-LABEL: @f7(
+// CHECK-NEXT:  entry:
+// CHECK-NEXT:[[TMP0:%.*]] = load i128, ptr @Val, align 16, !tbaa [[TBAA2]]
+// CHECK-NEXT:[[TMP1:%.*]] = atomicrmw add ptr @Ptr, i128 

[PATCH] D141409: [SystemZ] Fix handling of vectors and their exposure of the vector ABI.

2023-01-27 Thread Jonas Paulsson 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 rG0eff46f87f16: [SystemZ] Fix handling of vectors and their 
exposure of the vector ABI. (authored by jonpa).
Herald added a project: clang.
Herald added a subscriber: cfe-commits.

Changed prior to commit:
  https://reviews.llvm.org/D141409?vs=492794=492858#toc

Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D141409

Files:
  clang/lib/CodeGen/TargetInfo.cpp
  clang/test/CodeGen/SystemZ/vec-abi-gnuattr-03b.c
  clang/test/CodeGen/SystemZ/vec-abi-gnuattr-08b.c
  clang/test/CodeGen/SystemZ/vec-abi-gnuattr-09b.c
  clang/test/CodeGen/SystemZ/vec-abi-gnuattr-17b.c
  clang/test/CodeGen/SystemZ/vec-abi-gnuattr-24.c

Index: clang/test/CodeGen/SystemZ/vec-abi-gnuattr-24.c
===
--- clang/test/CodeGen/SystemZ/vec-abi-gnuattr-24.c
+++ clang/test/CodeGen/SystemZ/vec-abi-gnuattr-24.c
@@ -34,4 +34,20 @@
   return foo(V)[0] + GlobVal + GlobExtVar;
 }
 
+// Globally visible vector variable less than 16 bytes in size.
+typedef __attribute__((vector_size(8))) int v2i32;
+v2i32 NarrowVecVar;
+
+// Global function taking narrow vector array and pointer.
+void bar(v2i32 VArr[4], v2i32 *Dst) { *Dst = VArr[3]; }
+
+// Wide vector parameters via "hidden" pointers.
+typedef __attribute__((vector_size(32))) int v8i32;
+v8i32 bar2(v8i32 Arg) { return Arg; }
+
+// Same but with a single element struct.
+struct SingleElStruct { v8i32 B; };
+struct SingleElStruct bar3(struct SingleElStruct Arg) { return Arg; }
+
+
 //CHECK-NOT: !{i32 2, !"s390x-visible-vector-ABI", i32 1}
Index: clang/test/CodeGen/SystemZ/vec-abi-gnuattr-17b.c
===
--- /dev/null
+++ clang/test/CodeGen/SystemZ/vec-abi-gnuattr-17b.c
@@ -0,0 +1,13 @@
+// RUN: %clang_cc1 -triple s390x-ibm-linux -emit-llvm -fzvector -o - %s 2>&1 \
+// RUN:   | FileCheck  %s
+//
+// Test that the "s390x-visible-vector-ABI" module flag is emitted.
+
+// Globally visible function pointer with narrow vector argument.
+
+typedef __attribute__((vector_size(8))) int v2i32;
+
+void (*bar)(v2i32 Arg);
+
+//CHECK: !llvm.module.flags = !{!0, !1}
+//CHECK: !0 = !{i32 2, !"s390x-visible-vector-ABI", i32 1}
Index: clang/test/CodeGen/SystemZ/vec-abi-gnuattr-09b.c
===
--- /dev/null
+++ clang/test/CodeGen/SystemZ/vec-abi-gnuattr-09b.c
@@ -0,0 +1,18 @@
+// RUN: %clang_cc1 -triple s390x-ibm-linux -emit-llvm -fzvector -o - %s 2>&1 \
+// RUN:   | FileCheck  %s
+//
+// Test the emission of the "s390x-visible-vector-ABI" module flag.
+
+// Call to vararg function with a narrow (8 bytes) vector argument.
+
+typedef __attribute__((vector_size(8))) int v2i32;
+
+void bar(int N, ...);
+
+void foo() {
+  v2i32 Var = {0, 0};
+  bar(0, Var);
+}
+
+//CHECK: !llvm.module.flags = !{!0, !1}
+//CHECK: !0 = !{i32 2, !"s390x-visible-vector-ABI", i32 1}
Index: clang/test/CodeGen/SystemZ/vec-abi-gnuattr-08b.c
===
--- /dev/null
+++ clang/test/CodeGen/SystemZ/vec-abi-gnuattr-08b.c
@@ -0,0 +1,22 @@
+// RUN: %clang_cc1 -triple s390x-ibm-linux -emit-llvm -fzvector -o - %s 2>&1 \
+// RUN:   | FileCheck  %s
+//
+// Test the emission of the "s390x-visible-vector-ABI" module flag.
+
+// Passing a single element struct containing a narrow (8 byte) vector element.
+
+typedef __attribute__((vector_size(8))) int v2i32;
+
+struct S {
+  v2i32 B;
+};
+
+void bar(struct S Arg);
+
+void foo() {
+  struct S Var = {{0, 0}};
+  bar(Var);
+}
+
+//CHECK: !llvm.module.flags = !{!0, !1}
+//CHECK: !0 = !{i32 2, !"s390x-visible-vector-ABI", i32 1}
Index: clang/test/CodeGen/SystemZ/vec-abi-gnuattr-03b.c
===
--- /dev/null
+++ clang/test/CodeGen/SystemZ/vec-abi-gnuattr-03b.c
@@ -0,0 +1,19 @@
+// RUN: %clang_cc1 -triple s390x-ibm-linux -emit-llvm -fzvector -o - %s 2>&1 \
+// RUN:   | FileCheck  %s
+//
+// Test that the "s390x-visible-vector-ABI" module flag is emitted.
+
+// Call to external function with with narrow vector argument.
+
+typedef __attribute__((vector_size(8))) int v2i32;
+
+void bar(v2i32 arg);
+
+void foo() {
+  v2i32 Var = {0, 0};
+  bar(Var);
+}
+
+//CHECK: !llvm.module.flags = !{!0, !1}
+//CHECK: !0 = !{i32 2, !"s390x-visible-vector-ABI", i32 1}
+
Index: clang/lib/CodeGen/TargetInfo.cpp
===
--- clang/lib/CodeGen/TargetInfo.cpp
+++ clang/lib/CodeGen/TargetInfo.cpp
@@ -7418,18 +7418,28 @@
 };
 
 class SystemZTargetCodeGenInfo : public TargetCodeGenInfo {
+  ASTContext 
+
+  const SystemZABIInfo () const {
+return static_cast(TargetCodeGenInfo::getABIInfo());
+  }
+
   // These are used for speeding up the search for a visible vector 

[PATCH] D105067: [SystemZ] Emit .gnu_attribute for an externally visible vector abi.

2022-12-06 Thread Jonas Paulsson via Phabricator via cfe-commits
This revision was landed with ongoing or failed builds.
This revision was automatically updated to reflect the committed changes.
jonpa marked an inline comment as done.
Closed by commit rG481bb44baab5: [SystemZ] Emit a .gnu_attribute for an 
externally visible vector abi. (authored by jonpa).
Herald added a project: clang.
Herald added a subscriber: cfe-commits.

Changed prior to commit:
  https://reviews.llvm.org/D105067?vs=480520=480550#toc

Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D105067

Files:
  clang/lib/CodeGen/CodeGenTypes.h
  clang/lib/CodeGen/TargetInfo.cpp
  clang/test/CodeGen/SystemZ/vec-abi-gnuattr-00.c
  clang/test/CodeGen/SystemZ/vec-abi-gnuattr-01.c
  clang/test/CodeGen/SystemZ/vec-abi-gnuattr-02.c
  clang/test/CodeGen/SystemZ/vec-abi-gnuattr-03.c
  clang/test/CodeGen/SystemZ/vec-abi-gnuattr-04.c
  clang/test/CodeGen/SystemZ/vec-abi-gnuattr-05.c
  clang/test/CodeGen/SystemZ/vec-abi-gnuattr-06.c
  clang/test/CodeGen/SystemZ/vec-abi-gnuattr-07.c
  clang/test/CodeGen/SystemZ/vec-abi-gnuattr-08.c
  clang/test/CodeGen/SystemZ/vec-abi-gnuattr-09.c
  clang/test/CodeGen/SystemZ/vec-abi-gnuattr-10.c
  clang/test/CodeGen/SystemZ/vec-abi-gnuattr-11.c
  clang/test/CodeGen/SystemZ/vec-abi-gnuattr-12.c
  clang/test/CodeGen/SystemZ/vec-abi-gnuattr-13.c
  clang/test/CodeGen/SystemZ/vec-abi-gnuattr-14.c
  clang/test/CodeGen/SystemZ/vec-abi-gnuattr-15.c
  clang/test/CodeGen/SystemZ/vec-abi-gnuattr-16.c
  clang/test/CodeGen/SystemZ/vec-abi-gnuattr-17.c
  clang/test/CodeGen/SystemZ/vec-abi-gnuattr-18.c
  clang/test/CodeGen/SystemZ/vec-abi-gnuattr-19.c
  clang/test/CodeGen/SystemZ/vec-abi-gnuattr-20.cpp
  clang/test/CodeGen/SystemZ/vec-abi-gnuattr-21.c
  clang/test/CodeGen/SystemZ/vec-abi-gnuattr-22.c
  clang/test/CodeGen/SystemZ/vec-abi-gnuattr-23.c
  clang/test/CodeGen/SystemZ/vec-abi-gnuattr-24.c
  llvm/lib/Target/SystemZ/AsmParser/SystemZAsmParser.cpp
  llvm/lib/Target/SystemZ/SystemZAsmPrinter.cpp
  llvm/lib/Target/SystemZ/SystemZAsmPrinter.h
  llvm/test/MC/SystemZ/gnu-attributes.s

Index: llvm/test/MC/SystemZ/gnu-attributes.s
===
--- /dev/null
+++ llvm/test/MC/SystemZ/gnu-attributes.s
@@ -0,0 +1,17 @@
+# RUN: llvm-mc -triple s390x-linux-gnu -filetype=asm %s | \
+# RUN: FileCheck %s --check-prefix=ASM
+# RUN: llvm-mc -triple s390x-linux-gnu -filetype=obj %s | \
+# RUN: llvm-objdump --mcpu=z14 -D - | FileCheck %s --check-prefix=OBJ
+
+#ASM:  .text
+#ASM:  .gnu_attribute 8, 2
+
+#OBJ:   <.gnu.attributes>:
+#OBJ:   0: 41 00 00 00
+#OBJ:   4: 0f 67
+#OBJ:   6: 6e 75 00 01
+#OBJ:   a: 00 00
+#OBJ:   c: 00 07
+#OBJ:   e: 08 02
+
+  .gnu_attribute 8, 2
Index: llvm/lib/Target/SystemZ/SystemZAsmPrinter.h
===
--- llvm/lib/Target/SystemZ/SystemZAsmPrinter.h
+++ llvm/lib/Target/SystemZ/SystemZAsmPrinter.h
@@ -57,6 +57,7 @@
   StringRef getPassName() const override { return "SystemZ Assembly Printer"; }
   void emitInstruction(const MachineInstr *MI) override;
   void emitMachineConstantPoolValue(MachineConstantPoolValue *MCPV) override;
+  void emitEndOfAsmFile(Module ) override;
   bool PrintAsmOperand(const MachineInstr *MI, unsigned OpNo,
const char *ExtraCode, raw_ostream ) override;
   bool PrintAsmMemoryOperand(const MachineInstr *MI, unsigned OpNo,
@@ -74,6 +75,7 @@
   void LowerFENTRY_CALL(const MachineInstr , SystemZMCInstLower );
   void LowerSTACKMAP(const MachineInstr );
   void LowerPATCHPOINT(const MachineInstr , SystemZMCInstLower );
+  void emitAttributes(Module );
 };
 } // end namespace llvm
 
Index: llvm/lib/Target/SystemZ/SystemZAsmPrinter.cpp
===
--- llvm/lib/Target/SystemZ/SystemZAsmPrinter.cpp
+++ llvm/lib/Target/SystemZ/SystemZAsmPrinter.cpp
@@ -759,6 +759,17 @@
 getSubtargetInfo());
 }
 
+// The *alignment* of 128-bit vector types is different between the software
+// and hardware vector ABIs. If the there is an externally visible use of a
+// vector type in the module it should be annotated with an attribute.
+void SystemZAsmPrinter::emitAttributes(Module ) {
+  if (M.getModuleFlag("s390x-visible-vector-ABI")) {
+bool HasVectorFeature =
+  TM.getMCSubtargetInfo()->getFeatureBits()[SystemZ::FeatureVector];
+OutStreamer->emitGNUAttribute(8, HasVectorFeature ? 2 : 1);
+  }
+}
+
 // Convert a SystemZ-specific constant pool modifier into the associated
 // MCSymbolRefExpr variant kind.
 static MCSymbolRefExpr::VariantKind
@@ -859,6 +870,10 @@
   return false;
 }
 
+void SystemZAsmPrinter::emitEndOfAsmFile(Module ) {
+  emitAttributes(M);
+}
+
 void SystemZAsmPrinter::emitFunctionBodyEnd() {
   if (TM.getTargetTriple().isOSzOS()) {
 // Emit symbol for the end of function if the z/OS target streamer
Index: 

[PATCH] D137044: [ClangFE] Add support for option -mno-pic-data-is-text-relative

2022-11-22 Thread Jonas Paulsson via Phabricator via cfe-commits
jonpa added a comment.

In D137044#3943829 , @Fznamznon wrote:

> In D137044#3943680 , @jonpa wrote:
>
>> In D137044#3942990 , @pcwang-thead 
>> wrote:
>>
>>> The test `clang/test/Driver/pic.c` failed when we compiled Clang/LLVM with 
>>> `-DCLANG_DEFAULT_PIE_ON_LINUX=False`.
>>
>> Ah... I suppose that must be because -mno-pic-data-is-text-relative requires 
>> PIC (this is per GCC behavior). Does it help if you add -fpic to the RUN 
>> lines that were added by this patch? I was not aware of the cmake flag, 
>> sorry.
>
> For me it does. Can we make this change?

Yes, that should be fine as the test is assuming pic by default. Thanks.


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D137044

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


[PATCH] D137044: [ClangFE] Add support for option -mno-pic-data-is-text-relative

2022-11-22 Thread Jonas Paulsson via Phabricator via cfe-commits
jonpa added a comment.

In D137044#3942990 , @pcwang-thead 
wrote:

> The test `clang/test/Driver/pic.c` failed when we compiled Clang/LLVM with 
> `-DCLANG_DEFAULT_PIE_ON_LINUX=False`.

Ah... I suppose that must be because -mno-pic-data-is-text-relative requires 
PIC (this is per GCC behavior). Does it help if you add -fpic to the RUN lines 
that were added by this patch? I was not aware of the cmake flag, sorry.


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D137044

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


[PATCH] D137044: [ClangFE] Add support for option -mno-pic-data-is-text-relative

2022-11-17 Thread Jonas Paulsson via Phabricator via cfe-commits
This revision was automatically updated to reflect the committed changes.
Closed by commit rG858f347c1758: [Clang, SystemZ] Add support for option 
-mno-pic-data-is-text-relative. (authored by jonpa).
Herald added a project: clang.
Herald added a subscriber: cfe-commits.

Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D137044

Files:
  clang/include/clang/Driver/Options.td
  clang/lib/Driver/ToolChains/Clang.cpp
  clang/test/Driver/pic.c


Index: clang/test/Driver/pic.c
===
--- clang/test/Driver/pic.c
+++ clang/test/Driver/pic.c
@@ -1,5 +1,5 @@
-// Test the driver's control over the PIC behavior. These consist of tests of
-// the relocation model flags and the pic level flags passed to CC1.
+// Test the driver's control over the PIC behavior. These mainly consist of
+// tests of the relocation model flags and the pic level flags passed to CC1.
 //
 // CHECK-NO-PIC: "-mrelocation-model" "static"
 // CHECK-NO-PIC-NOT: "-pic-level"
@@ -45,6 +45,11 @@
 //
 // CHECK-NO-UNUSED-ARG-NOT: argument unused during compilation
 //
+// CHECK-NO-PIC-DATA-TEXT-REL: "-mcmodel=medium"
+// CHECK-PIC-DATA-TEXT-REL-NOT: "-mcmodel=medium"
+// CHECK-NO-PIC-DATA-TEXT-REL-NON-SYSTEMZ: error: unsupported option 
'-mno-pic-data-is-text-relative' for target 'arm-arm-none-eabi'
+// CHECK-PIC-DATA-TEXT-REL-NON-SYSTEMZ: error: unsupported option 
'-mpic-data-is-text-relative' for target 'arm-arm-none-eabi'
+//
 // RUN: %clang -c %s -target i386-unknown-unknown -### 2>&1 \
 // RUN:   | FileCheck %s --check-prefix=CHECK-NO-PIC
 // RUN: %clang -c %s -target i386-unknown-unknown -fpic -### 2>&1 \
@@ -313,3 +318,12 @@
 // RUN:   | FileCheck %s --check-prefix=CHECK-PIC2
 // RUN: %clang -fPIC -c %s -target armv7-pc-windows-gnu -### 2>&1 \
 // RUN:   | FileCheck %s --check-prefix=CHECK-NO-PIC
+
+// RUN: %clang -c --target=s390x-linux-gnu -mno-pic-data-is-text-relative %s \
+// RUN:   -### 2>&1 | FileCheck %s --check-prefix=CHECK-NO-PIC-DATA-TEXT-REL
+// RUN: %clang -c --target=s390x-linux-gnu -mpic-data-is-text-relative %s -### 
\
+// RUN:   2>&1 | FileCheck %s --check-prefix=CHECK-PIC-DATA-TEXT-REL
+// RUN: %clang -c --target=arm-arm-none-eabi -mno-pic-data-is-text-relative %s 
\
+// RUN:   -### 2>&1 | FileCheck %s 
--check-prefix=CHECK-NO-PIC-DATA-TEXT-REL-NON-SYSTEMZ
+// RUN: %clang -c --target=arm-arm-none-eabi -mpic-data-is-text-relative %s \
+// RUN:   -### 2>&1 | FileCheck %s 
--check-prefix=CHECK-PIC-DATA-TEXT-REL-NON-SYSTEMZ
Index: clang/lib/Driver/ToolChains/Clang.cpp
===
--- clang/lib/Driver/ToolChains/Clang.cpp
+++ clang/lib/Driver/ToolChains/Clang.cpp
@@ -5104,6 +5104,25 @@
   unsigned PICLevel;
   bool IsPIE;
   std::tie(RelocationModel, PICLevel, IsPIE) = ParsePICArgs(TC, Args);
+  Arg *LastPICDataRelArg =
+  Args.getLastArg(options::OPT_mno_pic_data_is_text_relative,
+  options::OPT_mpic_data_is_text_relative);
+  bool NoPICDataIsTextRelative = false;
+  if (LastPICDataRelArg) {
+if (LastPICDataRelArg->getOption().matches(
+options::OPT_mno_pic_data_is_text_relative)) {
+  NoPICDataIsTextRelative = true;
+  if (!PICLevel)
+D.Diag(diag::err_drv_argument_only_allowed_with)
+<< "-mno-pic-data-is-text-relative"
+<< "-fpic/-fpie";
+}
+if (!Triple.isSystemZ())
+  D.Diag(diag::err_drv_unsupported_opt_for_target)
+  << (NoPICDataIsTextRelative ? "-mno-pic-data-is-text-relative"
+  : "-mpic-data-is-text-relative")
+  << RawTriple.str();
+  }
 
   bool IsROPI = RelocationModel == llvm::Reloc::ROPI ||
 RelocationModel == llvm::Reloc::ROPI_RWPI;
@@ -5132,6 +5151,8 @@
 CmdArgs.push_back(PICLevel == 1 ? "1" : "2");
 if (IsPIE)
   CmdArgs.push_back("-pic-is-pie");
+if (NoPICDataIsTextRelative)
+  CmdArgs.push_back("-mcmodel=medium");
   }
 
   if (RelocationModel == llvm::Reloc::ROPI ||
Index: clang/include/clang/Driver/Options.td
===
--- clang/include/clang/Driver/Options.td
+++ clang/include/clang/Driver/Options.td
@@ -2697,6 +2697,8 @@
 def fno_pic : Flag<["-"], "fno-pic">, Group;
 def fpie : Flag<["-"], "fpie">, Group;
 def fno_pie : Flag<["-"], "fno-pie">, Group;
+defm pic_data_is_text_relative : SimpleMFlag<"pic-data-is-text-relative",
+ "Assume", "Don't assume", " data segments are relative to text segment">;
 def fdirect_access_external_data : Flag<["-"], 
"fdirect-access-external-data">, Group, Flags<[CC1Option]>,
   HelpText<"Don't use GOT indirection to reference external data symbols">;
 def fno_direct_access_external_data : Flag<["-"], 
"fno-direct-access-external-data">, Group, Flags<[CC1Option]>,


Index: clang/test/Driver/pic.c

[PATCH] D131158: [SystemZ] Improve handling of vector alignments

2022-09-08 Thread Jonas Paulsson 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 rGde0e3117d40a: [SystemZ] Improve handling of vector 
alignments. (authored by jonpa).
Herald added a project: clang.
Herald added a subscriber: cfe-commits.

Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D131158

Files:
  clang/lib/Basic/Targets/SystemZ.h
  clang/test/CodeGen/SystemZ/align-systemz-02.c
  clang/test/CodeGen/target-data.c
  llvm/lib/Target/SystemZ/SystemZTargetMachine.cpp
  llvm/test/CodeGen/SystemZ/function-attributes-01.ll
  llvm/test/CodeGen/SystemZ/vec-abi-align.ll

Index: llvm/test/CodeGen/SystemZ/vec-abi-align.ll
===
--- llvm/test/CodeGen/SystemZ/vec-abi-align.ll
+++ llvm/test/CodeGen/SystemZ/vec-abi-align.ll
@@ -1,55 +1,73 @@
-; Verify that we use the vector ABI datalayout if and only if
-; the vector facility is present.
+; Verify that a struct as generated by the frontend is correctly accessed in
+; both cases of enabling/disabling the vector facility.
 ;
 ; RUN: llc < %s -mtriple=s390x-linux-gnu | \
-; RUN:   FileCheck -check-prefix=CHECK-NOVECTOR %s
+; RUN:   FileCheck -check-prefixes=CHECK,CHECK-NOVECTOR %s
 ; RUN: llc < %s -mtriple=s390x-linux-gnu -mcpu=generic | \
-; RUN:   FileCheck -check-prefix=CHECK-NOVECTOR %s
+; RUN:   FileCheck -check-prefixes=CHECK,CHECK-NOVECTOR %s
 ; RUN: llc < %s -mtriple=s390x-linux-gnu -mcpu=z10 | \
-; RUN:   FileCheck -check-prefix=CHECK-NOVECTOR %s
+; RUN:   FileCheck -check-prefixes=CHECK,CHECK-NOVECTOR %s
 ; RUN: llc < %s -mtriple=s390x-linux-gnu -mcpu=z196 | \
-; RUN:   FileCheck -check-prefix=CHECK-NOVECTOR %s
+; RUN:   FileCheck -check-prefixes=CHECK,CHECK-NOVECTOR %s
 ; RUN: llc < %s -mtriple=s390x-linux-gnu -mcpu=zEC12 | \
-; RUN:   FileCheck -check-prefix=CHECK-NOVECTOR %s
+; RUN:   FileCheck -check-prefixes=CHECK,CHECK-NOVECTOR %s
 ; RUN: llc < %s -mtriple=s390x-linux-gnu -mcpu=z13 | \
-; RUN:   FileCheck -check-prefix=CHECK-VECTOR %s
+; RUN:   FileCheck -check-prefixes=CHECK,CHECK-VECTOR %s
 
 ; RUN: llc < %s -mtriple=s390x-linux-gnu -mattr=vector | \
-; RUN:   FileCheck -check-prefix=CHECK-VECTOR %s
+; RUN:   FileCheck -check-prefixes=CHECK,CHECK-VECTOR %s
 ; RUN: llc < %s -mtriple=s390x-linux-gnu -mattr=+vector | \
-; RUN:   FileCheck -check-prefix=CHECK-VECTOR %s
+; RUN:   FileCheck -check-prefixes=CHECK,CHECK-VECTOR %s
 ; RUN: llc < %s -mtriple=s390x-linux-gnu -mattr=-vector,vector | \
-; RUN:   FileCheck -check-prefix=CHECK-VECTOR %s
+; RUN:   FileCheck -check-prefixes=CHECK,CHECK-VECTOR %s
 ; RUN: llc < %s -mtriple=s390x-linux-gnu -mattr=-vector,+vector | \
-; RUN:   FileCheck -check-prefix=CHECK-VECTOR %s
+; RUN:   FileCheck -check-prefixes=CHECK,CHECK-VECTOR %s
 ; RUN: llc < %s -mtriple=s390x-linux-gnu -mattr=-vector | \
-; RUN:   FileCheck -check-prefix=CHECK-NOVECTOR %s
+; RUN:   FileCheck -check-prefixes=CHECK,CHECK-NOVECTOR %s
 ; RUN: llc < %s -mtriple=s390x-linux-gnu -mattr=vector,-vector | \
-; RUN:   FileCheck -check-prefix=CHECK-NOVECTOR %s
+; RUN:   FileCheck -check-prefixes=CHECK,CHECK-NOVECTOR %s
 ; RUN: llc < %s -mtriple=s390x-linux-gnu -mattr=+vector,-vector | \
-; RUN:   FileCheck -check-prefix=CHECK-NOVECTOR %s
+; RUN:   FileCheck -check-prefixes=CHECK,CHECK-NOVECTOR %s
 
 ; RUN: llc < %s -mtriple=s390x-linux-gnu -mcpu=z13 -mattr=-vector | \
-; RUN:   FileCheck -check-prefix=CHECK-NOVECTOR %s
+; RUN:   FileCheck -check-prefixes=CHECK,CHECK-NOVECTOR %s
 
 ; RUN: llc < %s -mtriple=s390x-linux-gnu -mcpu=z13 -mattr=+soft-float | \
-; RUN:   FileCheck -check-prefix=CHECK-NOVECTOR %s
+; RUN:   FileCheck -check-prefixes=CHECK,CHECK-NOVECTOR %s
 ; RUN: llc < %s -mtriple=s390x-linux-gnu -mcpu=z13 \
 ; RUN:   -mattr=soft-float,-soft-float | \
-; RUN:   FileCheck -check-prefix=CHECK-VECTOR %s
+; RUN:   FileCheck -check-prefixes=CHECK,CHECK-VECTOR %s
 ; RUN: llc < %s -mtriple=s390x-linux-gnu -mcpu=z13 \
 ; RUN:   -mattr=-soft-float,soft-float | \
-; RUN:   FileCheck -check-prefix=CHECK-NOVECTOR %s
+; RUN:   FileCheck -check-prefixes=CHECK,CHECK-NOVECTOR %s
 
-%struct.S = type { i8, <2 x i64> }
+%struct.S_vx = type { i8, <2 x i64> }
+%struct.S_novx = type { i8, [15 x i8], <2 x i64> }
 
-define void @test(%struct.S* %s) nounwind {
-; CHECK-VECTOR-LABEL: @test
+define void @fun_vx(%struct.S_vx* %s) nounwind {
+; CHECK-LABEL: @fun_vx
+;
 ; CHECK-VECTOR: vl %v0, 8(%r2)
-; CHECK-NOVECTOR-LABEL: @test
+; CHECK-VECTOR: vst %v0, 8(%r2), 3
+;
+; CHECK-NOVECTOR-DAG: agsi 16(%r2), 1
+; CHECK-NOVECTOR-DAG: agsi 8(%r2), 1
+  %ptr = getelementptr %struct.S_vx, %struct.S_vx* %s, i64 0, i32 1
+  %vec = load <2 x i64>, <2 x i64>* %ptr
+  %add = add <2 x i64> %vec, 
+  store <2 x i64> %add, <2 x i64>* %ptr
+  ret void
+}
+
+define void @fun_novx(%struct.S_novx* %s) nounwind {
+; CHECK-LABEL: @fun_novx
+;
+; CHECK-VECTOR: vl  %v0, 16(%r2), 3
+; 

[PATCH] D130900: [SystemZ] Make 128 bit integers be aligned to 8 bytes.

2022-08-03 Thread Jonas Paulsson 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 rG84831bdfedba: [SystemZ] Make 128 bit integers be aligned to 
8 bytes. (authored by jonpa).
Herald added a project: clang.
Herald added a subscriber: cfe-commits.

Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D130900

Files:
  clang/include/clang/Basic/TargetInfo.h
  clang/lib/AST/ASTContext.cpp
  clang/lib/Basic/TargetInfo.cpp
  clang/lib/Basic/Targets/SystemZ.h
  clang/test/CodeGen/SystemZ/align-systemz.c
  clang/test/CodeGen/SystemZ/systemz-abi.c
  clang/test/CodeGen/SystemZ/zos-alignment.c
  llvm/test/CodeGen/SystemZ/unaligned-02.ll

Index: llvm/test/CodeGen/SystemZ/unaligned-02.ll
===
--- /dev/null
+++ llvm/test/CodeGen/SystemZ/unaligned-02.ll
@@ -0,0 +1,13 @@
+; Check that an unaligned i128 access get the correct alignment added.
+;
+; RUN: llc < %s -mtriple=s390x-linux-gnu -stop-after=pre-isel-intrinsic-lowering \
+; RUN:   | FileCheck %s
+
+define void @f1(ptr %ptr) {
+; CHECK:   define void @f1(ptr %ptr) {
+; CHECK-NEXT:store i128 0, ptr %ptr, align 8
+; CHECK-NEXT:ret void
+; CHECK-NEXT:  }
+  store i128 0, ptr %ptr
+  ret void
+}
Index: clang/test/CodeGen/SystemZ/zos-alignment.c
===
--- clang/test/CodeGen/SystemZ/zos-alignment.c
+++ clang/test/CodeGen/SystemZ/zos-alignment.c
@@ -160,6 +160,13 @@
 // CHECK-NEXT: 8 |   char b
 // CHECK-NEXT:   | [sizeof=16, align=8]
 
+struct s12 {
+  __int128_t a;
+} S12;
+// CHECK:  0 | struct s12
+// CHECK-NEXT: 0 |   __int128_t a
+// CHECK-NEXT:   | [sizeof=16, align=8]
+
 union u0 {
   unsigned short d1 __attribute__((packed));
   int d2 : 10;
Index: clang/test/CodeGen/SystemZ/systemz-abi.c
===
--- clang/test/CodeGen/SystemZ/systemz-abi.c
+++ clang/test/CodeGen/SystemZ/systemz-abi.c
@@ -43,7 +43,7 @@
 // CHECK-LABEL: define{{.*}} i64 @pass_longlong(i64 %{{.*}})
 
 __int128 pass_int128(__int128 arg) { return arg; }
-// CHECK-LABEL: define{{.*}} void @pass_int128(i128* noalias sret(i128) align 16 %{{.*}}, i128* %0)
+// CHECK-LABEL: define{{.*}} void @pass_int128(i128* noalias sret(i128) align 8 %{{.*}}, i128* %0)
 
 float pass_float(float arg) { return arg; }
 // CHECK-LABEL: define{{.*}} float @pass_float(float %{{.*}})
Index: clang/test/CodeGen/SystemZ/align-systemz.c
===
--- clang/test/CodeGen/SystemZ/align-systemz.c
+++ clang/test/CodeGen/SystemZ/align-systemz.c
@@ -26,6 +26,14 @@
 }
 
 
+// The SystemZ ABI aligns __int128_t to only eight bytes.
+
+struct S_int128 {  __int128_t B; } Obj_I128;
+__int128_t GlobI128;
+// CHECK: @Obj_I128 = global %struct.S_int128 zeroinitializer, align 8
+// CHECK: @GlobI128 = global i128 0, align 8
+
+
 // Alignment should be respected for coerced argument loads
 
 struct arg { long y __attribute__((packed, aligned(4))); };
@@ -40,4 +48,3 @@
 
 // CHECK-LABEL: @test
 // CHECK: load i64, i64* getelementptr inbounds (%struct.arg, %struct.arg* @x, i32 0, i32 0), align 4
-
Index: clang/lib/Basic/Targets/SystemZ.h
===
--- clang/lib/Basic/Targets/SystemZ.h
+++ clang/lib/Basic/Targets/SystemZ.h
@@ -40,6 +40,7 @@
 TLSSupported = true;
 IntWidth = IntAlign = 32;
 LongWidth = LongLongWidth = LongAlign = LongLongAlign = 64;
+Int128Align = 64;
 PointerWidth = PointerAlign = 64;
 LongDoubleWidth = 128;
 LongDoubleAlign = 64;
Index: clang/lib/Basic/TargetInfo.cpp
===
--- clang/lib/Basic/TargetInfo.cpp
+++ clang/lib/Basic/TargetInfo.cpp
@@ -45,6 +45,7 @@
   IntWidth = IntAlign = 32;
   LongWidth = LongAlign = 32;
   LongLongWidth = LongLongAlign = 64;
+  Int128Align = 128;
 
   // Fixed point default bit widths
   ShortAccumWidth = ShortAccumAlign = 16;
Index: clang/lib/AST/ASTContext.cpp
===
--- clang/lib/AST/ASTContext.cpp
+++ clang/lib/AST/ASTContext.cpp
@@ -2082,7 +2082,7 @@
 case BuiltinType::Int128:
 case BuiltinType::UInt128:
   Width = 128;
-  Align = 128; // int128_t is 128-bit aligned on all targets.
+  Align = Target->getInt128Align();
   break;
 case BuiltinType::ShortAccum:
 case BuiltinType::UShortAccum:
Index: clang/include/clang/Basic/TargetInfo.h
===
--- clang/include/clang/Basic/TargetInfo.h
+++ clang/include/clang/Basic/TargetInfo.h
@@ -78,6 +78,7 @@
   unsigned char LargeArrayMinWidth, LargeArrayAlign;
   unsigned char LongWidth, LongAlign;
   unsigned char LongLongWidth, 

[PATCH] D122388: [SystemZ] Fix C++ ABI for passing args of structs containing zero width bitfield.

2022-04-26 Thread Jonas Paulsson via Phabricator via cfe-commits
This revision was automatically updated to reflect the committed changes.
Closed by commit rG9b38e2efa0f0: [SystemZ] Fix C++ ABI for passing args of 
structs containing zero width… (authored by jonpa).
Herald added a project: clang.
Herald added a subscriber: cfe-commits.

Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D122388

Files:
  clang/lib/CodeGen/TargetInfo.cpp
  clang/test/CodeGen/SystemZ/systemz-abi.cpp


Index: clang/test/CodeGen/SystemZ/systemz-abi.cpp
===
--- clang/test/CodeGen/SystemZ/systemz-abi.cpp
+++ clang/test/CodeGen/SystemZ/systemz-abi.cpp
@@ -15,12 +15,10 @@
 // SOFT-FLOAT-LABEL: define{{.*}} void 
@_Z21pass_agg_double_class16agg_double_class(%class.agg_double_class* noalias 
sret(%class.agg_double_class) align 8 %{{.*}}, i64 %{{.*}})
 
 
-// For compatibility with GCC, this structure is passed in an FPR in C++,
-// but passed in a GPR in C (checked in systemz-abi.c).
-
+// This structure is passed in a GPR in C++ (and C, checked in systemz-abi.c).
 struct agg_float_cpp { float a; int : 0; };
 struct agg_float_cpp pass_agg_float_cpp(struct agg_float_cpp arg) { return 
arg; }
-// CHECK-LABEL: define{{.*}} void 
@_Z18pass_agg_float_cpp13agg_float_cpp(%struct.agg_float_cpp* noalias 
sret(%struct.agg_float_cpp) align 4 %{{.*}}, float %{{.*}})
+// CHECK-LABEL: define{{.*}} void 
@_Z18pass_agg_float_cpp13agg_float_cpp(%struct.agg_float_cpp* noalias 
sret(%struct.agg_float_cpp) align 4 %{{.*}}, i32 %{{.*}})
 // SOFT-FLOAT-LABEL:  define{{.*}} void 
@_Z18pass_agg_float_cpp13agg_float_cpp(%struct.agg_float_cpp* noalias 
sret(%struct.agg_float_cpp) align 4 %{{.*}}, i32 %{{.*}})
 
 
Index: clang/lib/CodeGen/TargetInfo.cpp
===
--- clang/lib/CodeGen/TargetInfo.cpp
+++ clang/lib/CodeGen/TargetInfo.cpp
@@ -7514,12 +7514,9 @@
 
 // Check the fields.
 for (const auto *FD : RD->fields()) {
-  // For compatibility with GCC, ignore empty bitfields in C++ mode.
   // Unlike isSingleElementStruct(), empty structure and array fields
   // do count.  So do anonymous bitfields that aren't zero-sized.
-  if (getContext().getLangOpts().CPlusPlus &&
-  FD->isZeroLengthBitField(getContext()))
-continue;
+
   // Like isSingleElementStruct(), ignore C++20 empty data members.
   if (FD->hasAttr() &&
   isEmptyRecord(getContext(), FD->getType(), true))


Index: clang/test/CodeGen/SystemZ/systemz-abi.cpp
===
--- clang/test/CodeGen/SystemZ/systemz-abi.cpp
+++ clang/test/CodeGen/SystemZ/systemz-abi.cpp
@@ -15,12 +15,10 @@
 // SOFT-FLOAT-LABEL: define{{.*}} void @_Z21pass_agg_double_class16agg_double_class(%class.agg_double_class* noalias sret(%class.agg_double_class) align 8 %{{.*}}, i64 %{{.*}})
 
 
-// For compatibility with GCC, this structure is passed in an FPR in C++,
-// but passed in a GPR in C (checked in systemz-abi.c).
-
+// This structure is passed in a GPR in C++ (and C, checked in systemz-abi.c).
 struct agg_float_cpp { float a; int : 0; };
 struct agg_float_cpp pass_agg_float_cpp(struct agg_float_cpp arg) { return arg; }
-// CHECK-LABEL: define{{.*}} void @_Z18pass_agg_float_cpp13agg_float_cpp(%struct.agg_float_cpp* noalias sret(%struct.agg_float_cpp) align 4 %{{.*}}, float %{{.*}})
+// CHECK-LABEL: define{{.*}} void @_Z18pass_agg_float_cpp13agg_float_cpp(%struct.agg_float_cpp* noalias sret(%struct.agg_float_cpp) align 4 %{{.*}}, i32 %{{.*}})
 // SOFT-FLOAT-LABEL:  define{{.*}} void @_Z18pass_agg_float_cpp13agg_float_cpp(%struct.agg_float_cpp* noalias sret(%struct.agg_float_cpp) align 4 %{{.*}}, i32 %{{.*}})
 
 
Index: clang/lib/CodeGen/TargetInfo.cpp
===
--- clang/lib/CodeGen/TargetInfo.cpp
+++ clang/lib/CodeGen/TargetInfo.cpp
@@ -7514,12 +7514,9 @@
 
 // Check the fields.
 for (const auto *FD : RD->fields()) {
-  // For compatibility with GCC, ignore empty bitfields in C++ mode.
   // Unlike isSingleElementStruct(), empty structure and array fields
   // do count.  So do anonymous bitfields that aren't zero-sized.
-  if (getContext().getLangOpts().CPlusPlus &&
-  FD->isZeroLengthBitField(getContext()))
-continue;
+
   // Like isSingleElementStruct(), ignore C++20 empty data members.
   if (FD->hasAttr() &&
   isEmptyRecord(getContext(), FD->getType(), true))
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D110267: [InlineAsm, SystemZ] Handle inline assembly address operands.

2022-04-19 Thread Jonas Paulsson 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 rG4aa5dc15f086: [SystemZ] Handle SystemZ specific inline 
assembly address operands. (authored by jonpa).
Herald added a project: clang.
Herald added a subscriber: cfe-commits.

Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D110267

Files:
  clang/lib/Basic/Targets/SystemZ.cpp
  clang/lib/Basic/Targets/SystemZ.h
  clang/test/CodeGen/SystemZ/systemz-inline-asm-03.c
  llvm/include/llvm/IR/InlineAsm.h
  llvm/lib/Target/SystemZ/SystemZISelDAGToDAG.cpp
  llvm/lib/Target/SystemZ/SystemZISelLowering.cpp
  llvm/lib/Target/SystemZ/SystemZISelLowering.h
  llvm/test/CodeGen/SystemZ/inline-asm-addr.ll

Index: llvm/test/CodeGen/SystemZ/inline-asm-addr.ll
===
--- llvm/test/CodeGen/SystemZ/inline-asm-addr.ll
+++ llvm/test/CodeGen/SystemZ/inline-asm-addr.ll
@@ -4,6 +4,54 @@
 @A = global i64* null, align 8
 @Idx = global i64 0, align 8
 
+define i64 @fun_BD12_Q() {
+; CHECK-LABEL: fun_BD12_Q:
+; CHECK: #APP
+; CHECK: lay	%r2, 800(%r1)
+entry:
+  %0 = load i64*, i64** @A
+  %arrayidx = getelementptr inbounds i64, i64* %0, i64 100
+  %1 = tail call i64 asm "lay $0, $1", "=r,^ZQ"(i64* nonnull %arrayidx)
+  store i64 %1, i64* @Addr
+  ret i64 %1
+}
+
+define i64 @fun_BD12_R() {
+; CHECK-LABEL: fun_BD12_R:
+; CHECK: #APP
+; CHECK: lay	%r2, 800(%r1)
+entry:
+  %0 = load i64*, i64** @A
+  %arrayidx = getelementptr inbounds i64, i64* %0, i64 100
+  %1 = tail call i64 asm "lay $0, $1", "=r,^ZR"(i64* nonnull %arrayidx)
+  store i64 %1, i64* @Addr
+  ret i64 %1
+}
+
+define i64 @fun_BD12_S() {
+; CHECK-LABEL: fun_BD12_S:
+; CHECK: #APP
+; CHECK: lay	%r2, 800(%r1)
+entry:
+  %0 = load i64*, i64** @A
+  %arrayidx = getelementptr inbounds i64, i64* %0, i64 100
+  %1 = tail call i64 asm "lay $0, $1", "=r,^ZS"(i64* nonnull %arrayidx)
+  store i64 %1, i64* @Addr
+  ret i64 %1
+}
+
+define i64 @fun_BD12_T() {
+; CHECK-LABEL: fun_BD12_T:
+; CHECK: #APP
+; CHECK: lay	%r2, 800(%r1)
+entry:
+  %0 = load i64*, i64** @A
+  %arrayidx = getelementptr inbounds i64, i64* %0, i64 100
+  %1 = tail call i64 asm "lay $0, $1", "=r,^ZT"(i64* nonnull %arrayidx)
+  store i64 %1, i64* @Addr
+  ret i64 %1
+}
+
 define i64 @fun_BD12_p() {
 ; CHECK-LABEL: fun_BD12_p:
 ; CHECK: #APP
@@ -16,6 +64,62 @@
   ret i64 %1
 }
 
+define i64 @fun_BDX12_Q() {
+; CHECK-LABEL: fun_BDX12_Q:
+; CHECK: #APP
+; CHECK: lay	%r2, 800(%r2)
+entry:
+  %0 = load i64*, i64** @A
+  %1 = load i64, i64* @Idx
+  %add = add nsw i64 %1, 100
+  %arrayidx = getelementptr inbounds i64, i64* %0, i64 %add
+  %2 = tail call i64 asm "lay $0, $1", "=r,^ZQ"(i64* %arrayidx)
+  store i64 %2, i64* @Addr
+  ret i64 %2
+}
+
+define i64 @fun_BDX12_R() {
+; CHECK-LABEL: fun_BDX12_R:
+; CHECK: #APP
+; CHECK: lay	%r2, 800(%r1,%r2)
+entry:
+  %0 = load i64*, i64** @A
+  %1 = load i64, i64* @Idx
+  %add = add nsw i64 %1, 100
+  %arrayidx = getelementptr inbounds i64, i64* %0, i64 %add
+  %2 = tail call i64 asm "lay $0, $1", "=r,^ZR"(i64* %arrayidx)
+  store i64 %2, i64* @Addr
+  ret i64 %2
+}
+
+define i64 @fun_BDX12_S() {
+; CHECK-LABEL: fun_BDX12_S:
+; CHECK: #APP
+; CHECK: lay	%r2, 800(%r2)
+entry:
+  %0 = load i64*, i64** @A
+  %1 = load i64, i64* @Idx
+  %add = add nsw i64 %1, 100
+  %arrayidx = getelementptr inbounds i64, i64* %0, i64 %add
+  %2 = tail call i64 asm "lay $0, $1", "=r,^ZS"(i64* %arrayidx)
+  store i64 %2, i64* @Addr
+  ret i64 %2
+}
+
+define i64 @fun_BDX12_T() {
+; CHECK-LABEL: fun_BDX12_T:
+; CHECK: #APP
+; CHECK: lay	%r2, 800(%r1,%r2)
+entry:
+  %0 = load i64*, i64** @A
+  %1 = load i64, i64* @Idx
+  %add = add nsw i64 %1, 100
+  %arrayidx = getelementptr inbounds i64, i64* %0, i64 %add
+  %2 = tail call i64 asm "lay $0, $1", "=r,^ZT"(i64* %arrayidx)
+  store i64 %2, i64* @Addr
+  ret i64 %2
+}
+
 define i64 @fun_BDX12_p() {
 ; CHECK-LABEL: fun_BDX12_p:
 ; CHECK: #APP
@@ -30,6 +134,54 @@
   ret i64 %2
 }
 
+define i64 @fun_BD20_Q() {
+; CHECK-LABEL: fun_BD20_Q:
+; CHECK: #APP
+; CHECK: lay	%r2, 0(%r2)
+entry:
+  %0 = load i64*, i64** @A
+  %arrayidx = getelementptr inbounds i64, i64* %0, i64 1000
+  %1 = tail call i64 asm "lay $0, $1", "=r,^ZQ"(i64* nonnull %arrayidx)
+  store i64 %1, i64* @Addr
+  ret i64 %1
+}
+
+define i64 @fun_BD20_R() {
+; CHECK-LABEL: fun_BD20_R:
+; CHECK: #APP
+; CHECK: lay	%r2, 0(%r2)
+entry:
+  %0 = load i64*, i64** @A
+  %arrayidx = getelementptr inbounds i64, i64* %0, i64 1000
+  %1 = tail call i64 asm "lay $0, $1", "=r,^ZR"(i64* nonnull %arrayidx)
+  store i64 %1, i64* @Addr
+  ret i64 %1
+}
+
+define i64 @fun_BD20_S() {
+; CHECK-LABEL: fun_BD20_S:
+; CHECK: #APP
+; CHECK: lay	%r2, 8000(%r1)
+entry:
+  %0 = load i64*, i64** @A
+  %arrayidx = getelementptr inbounds i64, i64* %0, i64 1000
+  %1 = tail call i64 asm "lay $0, $1", "=r,^ZS"(i64* nonnull %arrayidx)
+  store 

[PATCH] D122220: [InlineAsm] Add support for address operands ("p").

2022-04-13 Thread Jonas Paulsson via Phabricator via cfe-commits
jonpa added a comment.

-no-opaque-pointers added to SystemZ clang test, per 532dc62 
.


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D10

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


[PATCH] D122220: [InlineAsm] Add support for address operands ("p").

2022-04-13 Thread Jonas Paulsson 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 rG46f83caebc8f: [InlineAsm] Add support for address operands 
(p). (authored by jonpa).
Herald added a project: clang.
Herald added a subscriber: cfe-commits.

Changed prior to commit:
  https://reviews.llvm.org/D10?vs=420424=422459#toc

Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D10

Files:
  clang/lib/Basic/Targets/SystemZ.h
  clang/lib/Basic/Targets/X86.cpp
  clang/test/CodeGen/SystemZ/systemz-inline-asm-03.c
  clang/test/CodeGen/asm.c
  llvm/docs/LangRef.rst
  llvm/include/llvm/CodeGen/TargetLowering.h
  llvm/include/llvm/IR/InlineAsm.h
  llvm/lib/CodeGen/CodeGenPrepare.cpp
  llvm/lib/CodeGen/GlobalISel/InlineAsmLowering.cpp
  llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp
  llvm/lib/CodeGen/SelectionDAG/TargetLowering.cpp
  llvm/lib/Target/SystemZ/SystemZISelDAGToDAG.cpp
  llvm/lib/Target/X86/X86ISelDAGToDAG.cpp
  llvm/test/CodeGen/SystemZ/inline-asm-addr.ll
  llvm/test/CodeGen/X86/inline-asm-p-constraint.ll

Index: llvm/test/CodeGen/X86/inline-asm-p-constraint.ll
===
--- /dev/null
+++ llvm/test/CodeGen/X86/inline-asm-p-constraint.ll
@@ -0,0 +1,11 @@
+; RUN: llc -mtriple=x86_64-unknown-unknown -no-integrated-as < %s 2>&1 | FileCheck %s
+
+define i8* @foo(i8* %ptr) {
+; CHECK-LABEL: foo:
+  %1 = tail call i8* asm "lea $1, $0", "=r,p,~{dirflag},~{fpsr},~{flags}"(i8* %ptr)
+; CHECK:  #APP
+; CHECK-NEXT: lea (%rdi), %rax
+; CHECK-NEXT: #NO_APP
+  ret i8* %1
+; CHECK-NEXT: retq
+}
Index: llvm/test/CodeGen/SystemZ/inline-asm-addr.ll
===
--- /dev/null
+++ llvm/test/CodeGen/SystemZ/inline-asm-addr.ll
@@ -0,0 +1,57 @@
+; RUN: llc -mtriple=s390x-linux-gnu < %s | FileCheck %s
+
+@Addr = global i64 0, align 8
+@A = global i64* null, align 8
+@Idx = global i64 0, align 8
+
+define i64 @fun_BD12_p() {
+; CHECK-LABEL: fun_BD12_p:
+; CHECK: #APP
+; CHECK: lay	%r2, 800(%r1)
+entry:
+  %0 = load i64*, i64** @A
+  %arrayidx = getelementptr inbounds i64, i64* %0, i64 100
+  %1 = tail call i64 asm "lay $0, $1", "=r,p"(i64* nonnull %arrayidx)
+  store i64 %1, i64* @Addr
+  ret i64 %1
+}
+
+define i64 @fun_BDX12_p() {
+; CHECK-LABEL: fun_BDX12_p:
+; CHECK: #APP
+; CHECK: lay	%r2, 800(%r1,%r2)
+entry:
+  %0 = load i64*, i64** @A
+  %1 = load i64, i64* @Idx
+  %add = add nsw i64 %1, 100
+  %arrayidx = getelementptr inbounds i64, i64* %0, i64 %add
+  %2 = tail call i64 asm "lay $0, $1", "=r,p"(i64* %arrayidx)
+  store i64 %2, i64* @Addr
+  ret i64 %2
+}
+
+define i64 @fun_BD20_p() {
+; CHECK-LABEL: fun_BD20_p:
+; CHECK: #APP
+; CHECK: lay	%r2, 8000(%r1)
+entry:
+  %0 = load i64*, i64** @A
+  %arrayidx = getelementptr inbounds i64, i64* %0, i64 1000
+  %1 = tail call i64 asm "lay $0, $1", "=r,p"(i64* nonnull %arrayidx)
+  store i64 %1, i64* @Addr
+  ret i64 %1
+}
+
+define i64 @fun_BDX20_p() {
+; CHECK-LABEL: fun_BDX20_p:
+; CHECK: #APP
+; CHECK: lay	%r2, 8000(%r1,%r2)
+entry:
+  %0 = load i64*, i64** @A
+  %1 = load i64, i64* @Idx
+  %add = add nsw i64 %1, 1000
+  %arrayidx = getelementptr inbounds i64, i64* %0, i64 %add
+  %2 = tail call i64 asm "lay $0, $1", "=r,p"(i64* %arrayidx)
+  store i64 %2, i64* @Addr
+  ret i64 %2
+}
Index: llvm/lib/Target/X86/X86ISelDAGToDAG.cpp
===
--- llvm/lib/Target/X86/X86ISelDAGToDAG.cpp
+++ llvm/lib/Target/X86/X86ISelDAGToDAG.cpp
@@ -6176,6 +6176,7 @@
   case InlineAsm::Constraint_v: // not offsetable??
   case InlineAsm::Constraint_m: // memory
   case InlineAsm::Constraint_X:
+  case InlineAsm::Constraint_p: // address
 if (!selectAddr(nullptr, Op, Op0, Op1, Op2, Op3, Op4))
   return true;
 break;
Index: llvm/lib/Target/SystemZ/SystemZISelDAGToDAG.cpp
===
--- llvm/lib/Target/SystemZ/SystemZISelDAGToDAG.cpp
+++ llvm/lib/Target/SystemZ/SystemZISelDAGToDAG.cpp
@@ -1700,6 +1700,7 @@
   case InlineAsm::Constraint_T:
   case InlineAsm::Constraint_m:
   case InlineAsm::Constraint_o:
+  case InlineAsm::Constraint_p:
 // Accept an address with a long displacement and an index.
 // m works the same as T, as this is the most general case.
 // We don't really have any special handling of "offsettable"
Index: llvm/lib/CodeGen/SelectionDAG/TargetLowering.cpp
===
--- llvm/lib/CodeGen/SelectionDAG/TargetLowering.cpp
+++ llvm/lib/CodeGen/SelectionDAG/TargetLowering.cpp
@@ -4908,13 +4908,14 @@
 case 'o': // offsetable
 case 'V': // not offsetable
   return C_Memory;
+case 'p': // Address.
+  return C_Address;
 case 'n': // Simple Integer
 case 'E': // Floating Point Constant
 case 'F': 

[PATCH] D87279: [clang] Fix handling of physical registers in inline assembly operands.

2022-01-12 Thread Jonas Paulsson via Phabricator via cfe-commits
jonpa added a comment.

Sorry for the delay.

> This change seems like it's done in the wrong layer -- why do we add a 
> special-case in Clang to emit "={r11},{r11}", instead of fixing LLVM to not 
> break when given the previously-output "={r11},0"?

We were starting out with a test case that was the result of macro-intensive 
code (Linux kernel). It had a tied physreg def/use, with an additional use of 
the same physreg, which did not compile with clang. There were two problems: 
TwoAddress could not handle this case and therefore asserted, and also the 
extra COPY in the output of the same physreg that would also have to be dealt 
with.

Instead of trying to improve TwoAddress to recognize and handle a special case 
like this while also making sure no redundant COPYs would be produced, we found 
it more reasonable to handle this in the front end. The reasoning was that "= 
{r7},0" should be completely equivalent with "= {r7},{r7}", and they should be 
treated the same by the compiler. A tied physreg did not seem useful in the 
first place, so we decided to always emit the second form from the front end.

This is pretty much what the original commit message said: "Background: Macro 
intensive user code may contain inline assembly statements with multiple 
operands constrained to the same physreg. Such a case (with the operand 
constraints "+r" : "r") currently triggers the TwoAddressInstructionPass 
assertion against any extra use of a tied register. Furthermore, TwoAddress 
will insert a COPY to that physreg even though isel has already done so (for 
the non-tied use), which may lead to a second redundant instruction currently. 
A simple fix for this is to not emit tied physreg uses in the first place for 
the "+r" constraint, which is what this patch does."

> Furthermore, since earlyclobber was exempted from this change, doesn't the 
> same TwoAddressInstructionPass bug still affect earlyclobber uses?

I was never under the impression that this was a bug in TwoAddress, but rather 
an unhandled ("odd") case of phys-regs. ISel produced the first COPY, and 
TwoAddress the second one. How should that be cleaned up? Seemed best to avoid 
adding unnecessarily to TwoAddress if possible to avoid it...

Sorry, we don't have early clobber operands on SystemZ, so I haven't really 
thought much about that. We decided we had to exclude them from this patch per 
the reasoning of https://reviews.llvm.org/D87279#2334519.

So I would guess it might still be a problem to compile an early-clobber tied 
def/use of a physreg with an extra use (or several) of the same physreg. If 
that case is something you intend to handle, I would agree that perhaps then 
the front end change of this patch would not be needed anymore as it is the 
alternative approach.

> @nathanchance reports in https://github.com/ClangBuiltLinux/linux/issues/1512 
> that... now seems to be crashing as a result of this change.

I tested x.c, and it "works" on SystemZ, while it did not pass ISel on X86, 
from what I understand. Given the above reasoning of the equivalency between 
the two expressions (use either tied or explicit of the same phys-reg), I would 
also wonder if X86 is "choking on valid IR"...

As another matter, the SystemZ backend actually can't handle x.c, as it 
triggers `SpillGPRs.LowGPR != SpillGPRs.HighGPR && "Should be saving %r15 and 
something else". This is however a problem in the prologe/epilog emission if 
anything... I guess the case of just clobbering SP in a function has not been 
seen before.


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D87279

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


[PATCH] D96568: [CFE, SystemZ] Emit s390.tdc instrincic for __builtin_isnan in Constrained FP mode.

2021-06-22 Thread Jonas Paulsson via Phabricator via cfe-commits
jonpa added a comment.

In D96568#2832781 , @thopre wrote:

> In D96568#2569296 , @jonpa wrote:
>
>>> Sounds good to me. Hopefully I'll get round to __builtin_isinf soon and a 
>>> single hook will make the patch slightly smaller.
>>
>> Patch updated to call the new hook testFPKind() and make it take a BuiltinID 
>> as argument (that seems to work at least for the moment - maybe an enum type 
>> will become necessary at some point per your suggestion..?)
>>
>> I am not sure if this is "only" or "typically" used in constrained FP mode, 
>> or if the mode should be independent of calling this hook. The patch as it 
>> is asserts that it is called for an FP type but leaves it to the target to 
>> decide based on the FP mode, where SystemZ opts out unless it is constrained 
>> (which I think is what is wanted...).
>
> I forgot to ask at the time, why do you restrict this code to the constrained 
> case? Presumably it's a lot faster than fabs+cmp and should be faster in all 
> cases?

There are later optimizations that does this already in place (SystemZTDCPass). 
I checked now and it seems to make no difference at all to do this in the 
front-end always in non-constrained FP mode... (SPEC)


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D96568

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


[PATCH] D97901: [SystemZ] Test for infinity in testFPKind().

2021-03-15 Thread Jonas Paulsson 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 rG9cfd301ec8b5: [SystemZ] Test for isinf and isfinite in 
testFPKind(). (authored by jonpa).
Herald added a project: clang.

Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D97901

Files:
  clang/lib/CodeGen/TargetInfo.cpp
  clang/test/CodeGen/SystemZ/strictfp_builtins.c

Index: clang/test/CodeGen/SystemZ/strictfp_builtins.c
===
--- clang/test/CodeGen/SystemZ/strictfp_builtins.c
+++ clang/test/CodeGen/SystemZ/strictfp_builtins.c
@@ -9,7 +9,7 @@
 // CHECK-NEXT:[[F_ADDR:%.*]] = alloca float, align 4
 // CHECK-NEXT:store float [[F:%.*]], float* [[F_ADDR]], align 4
 // CHECK-NEXT:[[TMP0:%.*]] = load float, float* [[F_ADDR]], align 4
-// CHECK-NEXT:[[TMP1:%.*]] = call i32 @llvm.s390.tdc.f32(float [[TMP0]], i64 15) [[ATTR2:#.*]]
+// CHECK-NEXT:[[TMP1:%.*]] = call i32 @llvm.s390.tdc.f32(float [[TMP0]], i64 15) #[[ATTR2:[0-9]+]]
 // CHECK-NEXT:ret i32 [[TMP1]]
 //
 int test_isnan_float(float f) {
@@ -21,7 +21,7 @@
 // CHECK-NEXT:[[D_ADDR:%.*]] = alloca double, align 8
 // CHECK-NEXT:store double [[D:%.*]], double* [[D_ADDR]], align 8
 // CHECK-NEXT:[[TMP0:%.*]] = load double, double* [[D_ADDR]], align 8
-// CHECK-NEXT:[[TMP1:%.*]] = call i32 @llvm.s390.tdc.f64(double [[TMP0]], i64 15) [[ATTR2]]
+// CHECK-NEXT:[[TMP1:%.*]] = call i32 @llvm.s390.tdc.f64(double [[TMP0]], i64 15) #[[ATTR2]]
 // CHECK-NEXT:ret i32 [[TMP1]]
 //
 int test_isnan_double(double d) {
@@ -34,10 +34,84 @@
 // CHECK-NEXT:[[LD:%.*]] = load fp128, fp128* [[TMP0:%.*]], align 8
 // CHECK-NEXT:store fp128 [[LD]], fp128* [[LD_ADDR]], align 8
 // CHECK-NEXT:[[TMP1:%.*]] = load fp128, fp128* [[LD_ADDR]], align 8
-// CHECK-NEXT:[[TMP2:%.*]] = call i32 @llvm.s390.tdc.f128(fp128 [[TMP1]], i64 15) [[ATTR2]]
+// CHECK-NEXT:[[TMP2:%.*]] = call i32 @llvm.s390.tdc.f128(fp128 [[TMP1]], i64 15) #[[ATTR2]]
 // CHECK-NEXT:ret i32 [[TMP2]]
 //
 int test_isnan_long_double(long double ld) {
   return __builtin_isnan(ld);
 }
 
+// CHECK-LABEL: @test_isinf_float(
+// CHECK-NEXT:  entry:
+// CHECK-NEXT:[[F_ADDR:%.*]] = alloca float, align 4
+// CHECK-NEXT:store float [[F:%.*]], float* [[F_ADDR]], align 4
+// CHECK-NEXT:[[TMP0:%.*]] = load float, float* [[F_ADDR]], align 4
+// CHECK-NEXT:[[TMP1:%.*]] = call i32 @llvm.s390.tdc.f32(float [[TMP0]], i64 48) #[[ATTR2]]
+// CHECK-NEXT:ret i32 [[TMP1]]
+//
+int test_isinf_float(float f) {
+  return __builtin_isinf(f);
+}
+
+// CHECK-LABEL: @test_isinf_double(
+// CHECK-NEXT:  entry:
+// CHECK-NEXT:[[D_ADDR:%.*]] = alloca double, align 8
+// CHECK-NEXT:store double [[D:%.*]], double* [[D_ADDR]], align 8
+// CHECK-NEXT:[[TMP0:%.*]] = load double, double* [[D_ADDR]], align 8
+// CHECK-NEXT:[[TMP1:%.*]] = call i32 @llvm.s390.tdc.f64(double [[TMP0]], i64 48) #[[ATTR2]]
+// CHECK-NEXT:ret i32 [[TMP1]]
+//
+int test_isinf_double(double d) {
+  return __builtin_isinf(d);
+}
+
+// CHECK-LABEL: @test_isinf_long_double(
+// CHECK-NEXT:  entry:
+// CHECK-NEXT:[[LD_ADDR:%.*]] = alloca fp128, align 8
+// CHECK-NEXT:[[LD:%.*]] = load fp128, fp128* [[TMP0:%.*]], align 8
+// CHECK-NEXT:store fp128 [[LD]], fp128* [[LD_ADDR]], align 8
+// CHECK-NEXT:[[TMP1:%.*]] = load fp128, fp128* [[LD_ADDR]], align 8
+// CHECK-NEXT:[[TMP2:%.*]] = call i32 @llvm.s390.tdc.f128(fp128 [[TMP1]], i64 48) #[[ATTR2]]
+// CHECK-NEXT:ret i32 [[TMP2]]
+//
+int test_isinf_long_double(long double ld) {
+  return __builtin_isinf(ld);
+}
+
+// CHECK-LABEL: @test_isfinite_float(
+// CHECK-NEXT:  entry:
+// CHECK-NEXT:[[F_ADDR:%.*]] = alloca float, align 4
+// CHECK-NEXT:store float [[F:%.*]], float* [[F_ADDR]], align 4
+// CHECK-NEXT:[[TMP0:%.*]] = load float, float* [[F_ADDR]], align 4
+// CHECK-NEXT:[[TMP1:%.*]] = call i32 @llvm.s390.tdc.f32(float [[TMP0]], i64 4032) #[[ATTR2]]
+// CHECK-NEXT:ret i32 [[TMP1]]
+//
+int test_isfinite_float(float f) {
+  return __builtin_isfinite(f);
+}
+
+// CHECK-LABEL: @test_isfinite_double(
+// CHECK-NEXT:  entry:
+// CHECK-NEXT:[[D_ADDR:%.*]] = alloca double, align 8
+// CHECK-NEXT:store double [[D:%.*]], double* [[D_ADDR]], align 8
+// CHECK-NEXT:[[TMP0:%.*]] = load double, double* [[D_ADDR]], align 8
+// CHECK-NEXT:[[TMP1:%.*]] = call i32 @llvm.s390.tdc.f64(double [[TMP0]], i64 4032) #[[ATTR2]]
+// CHECK-NEXT:ret i32 [[TMP1]]
+//
+int test_isfinite_double(double d) {
+  return __builtin_isfinite(d);
+}
+
+// CHECK-LABEL: @test_isfinite_long_double(
+// CHECK-NEXT:  entry:
+// CHECK-NEXT:[[LD_ADDR:%.*]] = alloca fp128, align 8
+// CHECK-NEXT:[[LD:%.*]] = load fp128, fp128* [[TMP0:%.*]], align 8
+// CHECK-NEXT:store fp128 [[LD]], fp128* [[LD_ADDR]], align 8
+// 

[PATCH] D97901: [SystemZ] Test for infinity in testFPKind().

2021-03-15 Thread Jonas Paulsson via Phabricator via cfe-commits
jonpa updated this revision to Diff 330753.
jonpa added a comment.

> This "invert" logic doesn't look correct. "isfinite" and "isinf" both need to 
> return false on NaNs. I think you should just drop the invert logic and use a 
> TDC mask of 0xFC0 (zero, normal, or subnormal) to implement "isfinite".

Rebased and updated per review.


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

https://reviews.llvm.org/D97901

Files:
  clang/lib/CodeGen/TargetInfo.cpp
  clang/test/CodeGen/SystemZ/strictfp_builtins.c

Index: clang/test/CodeGen/SystemZ/strictfp_builtins.c
===
--- clang/test/CodeGen/SystemZ/strictfp_builtins.c
+++ clang/test/CodeGen/SystemZ/strictfp_builtins.c
@@ -9,7 +9,7 @@
 // CHECK-NEXT:[[F_ADDR:%.*]] = alloca float, align 4
 // CHECK-NEXT:store float [[F:%.*]], float* [[F_ADDR]], align 4
 // CHECK-NEXT:[[TMP0:%.*]] = load float, float* [[F_ADDR]], align 4
-// CHECK-NEXT:[[TMP1:%.*]] = call i32 @llvm.s390.tdc.f32(float [[TMP0]], i64 15) [[ATTR2:#.*]]
+// CHECK-NEXT:[[TMP1:%.*]] = call i32 @llvm.s390.tdc.f32(float [[TMP0]], i64 15) #[[ATTR2:[0-9]+]]
 // CHECK-NEXT:ret i32 [[TMP1]]
 //
 int test_isnan_float(float f) {
@@ -21,7 +21,7 @@
 // CHECK-NEXT:[[D_ADDR:%.*]] = alloca double, align 8
 // CHECK-NEXT:store double [[D:%.*]], double* [[D_ADDR]], align 8
 // CHECK-NEXT:[[TMP0:%.*]] = load double, double* [[D_ADDR]], align 8
-// CHECK-NEXT:[[TMP1:%.*]] = call i32 @llvm.s390.tdc.f64(double [[TMP0]], i64 15) [[ATTR2]]
+// CHECK-NEXT:[[TMP1:%.*]] = call i32 @llvm.s390.tdc.f64(double [[TMP0]], i64 15) #[[ATTR2]]
 // CHECK-NEXT:ret i32 [[TMP1]]
 //
 int test_isnan_double(double d) {
@@ -34,10 +34,84 @@
 // CHECK-NEXT:[[LD:%.*]] = load fp128, fp128* [[TMP0:%.*]], align 8
 // CHECK-NEXT:store fp128 [[LD]], fp128* [[LD_ADDR]], align 8
 // CHECK-NEXT:[[TMP1:%.*]] = load fp128, fp128* [[LD_ADDR]], align 8
-// CHECK-NEXT:[[TMP2:%.*]] = call i32 @llvm.s390.tdc.f128(fp128 [[TMP1]], i64 15) [[ATTR2]]
+// CHECK-NEXT:[[TMP2:%.*]] = call i32 @llvm.s390.tdc.f128(fp128 [[TMP1]], i64 15) #[[ATTR2]]
 // CHECK-NEXT:ret i32 [[TMP2]]
 //
 int test_isnan_long_double(long double ld) {
   return __builtin_isnan(ld);
 }
 
+// CHECK-LABEL: @test_isinf_float(
+// CHECK-NEXT:  entry:
+// CHECK-NEXT:[[F_ADDR:%.*]] = alloca float, align 4
+// CHECK-NEXT:store float [[F:%.*]], float* [[F_ADDR]], align 4
+// CHECK-NEXT:[[TMP0:%.*]] = load float, float* [[F_ADDR]], align 4
+// CHECK-NEXT:[[TMP1:%.*]] = call i32 @llvm.s390.tdc.f32(float [[TMP0]], i64 48) #[[ATTR2]]
+// CHECK-NEXT:ret i32 [[TMP1]]
+//
+int test_isinf_float(float f) {
+  return __builtin_isinf(f);
+}
+
+// CHECK-LABEL: @test_isinf_double(
+// CHECK-NEXT:  entry:
+// CHECK-NEXT:[[D_ADDR:%.*]] = alloca double, align 8
+// CHECK-NEXT:store double [[D:%.*]], double* [[D_ADDR]], align 8
+// CHECK-NEXT:[[TMP0:%.*]] = load double, double* [[D_ADDR]], align 8
+// CHECK-NEXT:[[TMP1:%.*]] = call i32 @llvm.s390.tdc.f64(double [[TMP0]], i64 48) #[[ATTR2]]
+// CHECK-NEXT:ret i32 [[TMP1]]
+//
+int test_isinf_double(double d) {
+  return __builtin_isinf(d);
+}
+
+// CHECK-LABEL: @test_isinf_long_double(
+// CHECK-NEXT:  entry:
+// CHECK-NEXT:[[LD_ADDR:%.*]] = alloca fp128, align 8
+// CHECK-NEXT:[[LD:%.*]] = load fp128, fp128* [[TMP0:%.*]], align 8
+// CHECK-NEXT:store fp128 [[LD]], fp128* [[LD_ADDR]], align 8
+// CHECK-NEXT:[[TMP1:%.*]] = load fp128, fp128* [[LD_ADDR]], align 8
+// CHECK-NEXT:[[TMP2:%.*]] = call i32 @llvm.s390.tdc.f128(fp128 [[TMP1]], i64 48) #[[ATTR2]]
+// CHECK-NEXT:ret i32 [[TMP2]]
+//
+int test_isinf_long_double(long double ld) {
+  return __builtin_isinf(ld);
+}
+
+// CHECK-LABEL: @test_isfinite_float(
+// CHECK-NEXT:  entry:
+// CHECK-NEXT:[[F_ADDR:%.*]] = alloca float, align 4
+// CHECK-NEXT:store float [[F:%.*]], float* [[F_ADDR]], align 4
+// CHECK-NEXT:[[TMP0:%.*]] = load float, float* [[F_ADDR]], align 4
+// CHECK-NEXT:[[TMP1:%.*]] = call i32 @llvm.s390.tdc.f32(float [[TMP0]], i64 4032) #[[ATTR2]]
+// CHECK-NEXT:ret i32 [[TMP1]]
+//
+int test_isfinite_float(float f) {
+  return __builtin_isfinite(f);
+}
+
+// CHECK-LABEL: @test_isfinite_double(
+// CHECK-NEXT:  entry:
+// CHECK-NEXT:[[D_ADDR:%.*]] = alloca double, align 8
+// CHECK-NEXT:store double [[D:%.*]], double* [[D_ADDR]], align 8
+// CHECK-NEXT:[[TMP0:%.*]] = load double, double* [[D_ADDR]], align 8
+// CHECK-NEXT:[[TMP1:%.*]] = call i32 @llvm.s390.tdc.f64(double [[TMP0]], i64 4032) #[[ATTR2]]
+// CHECK-NEXT:ret i32 [[TMP1]]
+//
+int test_isfinite_double(double d) {
+  return __builtin_isfinite(d);
+}
+
+// CHECK-LABEL: @test_isfinite_long_double(
+// CHECK-NEXT:  entry:
+// CHECK-NEXT:[[LD_ADDR:%.*]] = alloca fp128, align 8
+// CHECK-NEXT:[[LD:%.*]] = load fp128, fp128* [[TMP0:%.*]], align 8
+// CHECK-NEXT:store fp128 [[LD]], fp128* 

[PATCH] D97901: [SystemZ] Test for infinity in testFPKind().

2021-03-03 Thread Jonas Paulsson via Phabricator via cfe-commits
jonpa added inline comments.



Comment at: clang/lib/CodeGen/TargetInfo.cpp:7229
+  case Builtin::BI__builtin_isfinite:
+Invert = true;
+LLVM_FALLTHROUGH;

What are these variants all about...?



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

https://reviews.llvm.org/D97901

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


[PATCH] D97901: [SystemZ] Test for infinity in testFPKind().

2021-03-03 Thread Jonas Paulsson via Phabricator via cfe-commits
jonpa created this revision.
jonpa added reviewers: uweigand, thopre.
jonpa requested review of this revision.

Recognize __builtin_isinf and BI__builtin_isfinite (and a few other builtin 
opcodes for finite checks) in testFPKind().

TDC can check for infinity, and for finite with an inversion of the result.

'finite', '__finite', ... seemed to always work as double with 
extension/trunction from float/long double. I would guess it is expected to 
handle those as well with TDC, or?


https://reviews.llvm.org/D97901

Files:
  clang/lib/CodeGen/TargetInfo.cpp
  clang/test/CodeGen/SystemZ/strictfp_builtins.c

Index: clang/test/CodeGen/SystemZ/strictfp_builtins.c
===
--- clang/test/CodeGen/SystemZ/strictfp_builtins.c
+++ clang/test/CodeGen/SystemZ/strictfp_builtins.c
@@ -41,3 +41,80 @@
   return __builtin_isnan(ld);
 }
 
+// CHECK-LABEL: @test_isinf_float(
+// CHECK-NEXT:  entry:
+// CHECK-NEXT:[[F_ADDR:%.*]] = alloca float, align 4
+// CHECK-NEXT:store float [[F:%.*]], float* [[F_ADDR]], align 4
+// CHECK-NEXT:[[TMP0:%.*]] = load float, float* [[F_ADDR]], align 4
+// CHECK-NEXT:[[TMP1:%.*]] = call i32 @llvm.s390.tdc.f32(float [[TMP0]], i64 48) [[ATTR2]]
+// CHECK-NEXT:ret i32 [[TMP1]]
+//
+int test_isinf_float(float f) {
+  return __builtin_isinf(f);
+}
+
+// CHECK-LABEL: @test_isinf_double(
+// CHECK-NEXT:  entry:
+// CHECK-NEXT:[[D_ADDR:%.*]] = alloca double, align 8
+// CHECK-NEXT:store double [[D:%.*]], double* [[D_ADDR]], align 8
+// CHECK-NEXT:[[TMP0:%.*]] = load double, double* [[D_ADDR]], align 8
+// CHECK-NEXT:[[TMP1:%.*]] = call i32 @llvm.s390.tdc.f64(double [[TMP0]], i64 48) [[ATTR2]]
+// CHECK-NEXT:ret i32 [[TMP1]]
+//
+int test_isinf_double(double d) {
+  return __builtin_isinf(d);
+}
+
+// CHECK-LABEL: @test_isinf_long_double(
+// CHECK-NEXT:  entry:
+// CHECK-NEXT:[[LD_ADDR:%.*]] = alloca fp128, align 8
+// CHECK-NEXT:[[LD:%.*]] = load fp128, fp128* [[TMP0:%.*]], align 8
+// CHECK-NEXT:store fp128 [[LD]], fp128* [[LD_ADDR]], align 8
+// CHECK-NEXT:[[TMP1:%.*]] = load fp128, fp128* [[LD_ADDR]], align 8
+// CHECK-NEXT:[[TMP2:%.*]] = call i32 @llvm.s390.tdc.f128(fp128 [[TMP1]], i64 48) [[ATTR2]]
+// CHECK-NEXT:ret i32 [[TMP2]]
+//
+int test_isinf_long_double(long double ld) {
+  return __builtin_isinf(ld);
+}
+
+// CHECK-LABEL: @test_isfinite_float(
+// CHECK-NEXT:  entry:
+// CHECK-NEXT:[[F_ADDR:%.*]] = alloca float, align 4
+// CHECK-NEXT:store float [[F:%.*]], float* [[F_ADDR]], align 4
+// CHECK-NEXT:[[TMP0:%.*]] = load float, float* [[F_ADDR]], align 4
+// CHECK-NEXT:[[TMP1:%.*]] = call i32 @llvm.s390.tdc.f32(float [[TMP0]], i64 48) [[ATTR2]]
+// CHECK-NEXT:[[TMP2:%.*]] = xor i32 [[TMP1]], 1
+// CHECK-NEXT:ret i32 [[TMP2]]
+//
+int test_isfinite_float(float f) {
+  return __builtin_isfinite(f);
+}
+
+// CHECK-LABEL: @test_isfinite_double(
+// CHECK-NEXT:  entry:
+// CHECK-NEXT:[[D_ADDR:%.*]] = alloca double, align 8
+// CHECK-NEXT:store double [[D:%.*]], double* [[D_ADDR]], align 8
+// CHECK-NEXT:[[TMP0:%.*]] = load double, double* [[D_ADDR]], align 8
+// CHECK-NEXT:[[TMP1:%.*]] = call i32 @llvm.s390.tdc.f64(double [[TMP0]], i64 48) [[ATTR2]]
+// CHECK-NEXT:[[TMP2:%.*]] = xor i32 [[TMP1]], 1
+// CHECK-NEXT:ret i32 [[TMP2]]
+//
+int test_isfinite_double(double d) {
+  return __builtin_isfinite(d);
+}
+
+// CHECK-LABEL: @test_isfinite_long_double(
+// CHECK-NEXT:  entry:
+// CHECK-NEXT:[[LD_ADDR:%.*]] = alloca fp128, align 8
+// CHECK-NEXT:[[LD:%.*]] = load fp128, fp128* [[TMP0:%.*]], align 8
+// CHECK-NEXT:store fp128 [[LD]], fp128* [[LD_ADDR]], align 8
+// CHECK-NEXT:[[TMP1:%.*]] = load fp128, fp128* [[LD_ADDR]], align 8
+// CHECK-NEXT:[[TMP2:%.*]] = call i32 @llvm.s390.tdc.f128(fp128 [[TMP1]], i64 48) [[ATTR2]]
+// CHECK-NEXT:[[TMP3:%.*]] = xor i32 [[TMP2]], 1
+// CHECK-NEXT:ret i32 [[TMP3]]
+//
+int test_isfinite_long_double(long double ld) {
+  return __builtin_isfinite(ld);
+}
+
Index: clang/lib/CodeGen/TargetInfo.cpp
===
--- clang/lib/CodeGen/TargetInfo.cpp
+++ clang/lib/CodeGen/TargetInfo.cpp
@@ -7214,17 +7214,32 @@
   llvm::Function *TDCFunc =
   llvm::Intrinsic::getDeclaration(, llvm::Intrinsic::s390_tdc, Ty);
   unsigned TDCBits = 0;
+  bool Invert = false;
   switch (BuiltinID) {
   case Builtin::BI__builtin_isnan:
 TDCBits = 0xf;
 break;
+  case Builtin::BIfinite:
+  case Builtin::BI__finite:
+  case Builtin::BIfinitef:
+  case Builtin::BI__finitef:
+  case Builtin::BIfinitel:
+  case Builtin::BI__finitel:
+  case Builtin::BI__builtin_isfinite:
+Invert = true;
+LLVM_FALLTHROUGH;
+  case Builtin::BI__builtin_isinf:
+TDCBits = 0x30;
+break;
   default:
 break;
   }
-  if (TDCBits)
-

[PATCH] D97125: Stop traping on sNaN in __builtin_isinf

2021-02-22 Thread Jonas Paulsson via Phabricator via cfe-commits
jonpa added a comment.

In D97125#2578853 , @kpn wrote:

> System/Z's TEST DATA CLASS instruction covers most (all?) of the possible FP 
> value states. You might want to subscribe, or add as a reviewer, jonpa just 
> to make sure everyone stays in sync.

Thanks for keeping me updated on this - I see that you have already included 
the testFPKind() hook, so I will add these opcodes to SystemZ once this is 
committed...


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D97125

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


[PATCH] D96568: [CFE, SystemZ] Emit s390.tdc instrincic for __builtin_isnan in Constrained FP mode.

2021-02-18 Thread Jonas Paulsson via Phabricator via cfe-commits
This revision was automatically updated to reflect the committed changes.
Closed by commit rGe57bd1ff4fb6: [CFE, SystemZ]  New target hook testFPKind() 
for checks of FP values. (authored by jonpa).
Herald added a project: clang.

Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D96568

Files:
  clang/lib/CodeGen/CGBuiltin.cpp
  clang/lib/CodeGen/TargetInfo.cpp
  clang/lib/CodeGen/TargetInfo.h
  clang/test/CodeGen/SystemZ/strictfp_builtins.c

Index: clang/test/CodeGen/SystemZ/strictfp_builtins.c
===
--- /dev/null
+++ clang/test/CodeGen/SystemZ/strictfp_builtins.c
@@ -0,0 +1,43 @@
+// NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py
+// REQUIRES: systemz-registered-target
+// RUN: %clang_cc1 %s -emit-llvm -ffp-exception-behavior=maytrap -o - -triple s390x-linux-gnu | FileCheck %s
+
+#pragma float_control(except, on)
+
+// CHECK-LABEL: @test_isnan_float(
+// CHECK-NEXT:  entry:
+// CHECK-NEXT:[[F_ADDR:%.*]] = alloca float, align 4
+// CHECK-NEXT:store float [[F:%.*]], float* [[F_ADDR]], align 4
+// CHECK-NEXT:[[TMP0:%.*]] = load float, float* [[F_ADDR]], align 4
+// CHECK-NEXT:[[TMP1:%.*]] = call i32 @llvm.s390.tdc.f32(float [[TMP0]], i64 15) [[ATTR2:#.*]]
+// CHECK-NEXT:ret i32 [[TMP1]]
+//
+int test_isnan_float(float f) {
+  return __builtin_isnan(f);
+}
+
+// CHECK-LABEL: @test_isnan_double(
+// CHECK-NEXT:  entry:
+// CHECK-NEXT:[[D_ADDR:%.*]] = alloca double, align 8
+// CHECK-NEXT:store double [[D:%.*]], double* [[D_ADDR]], align 8
+// CHECK-NEXT:[[TMP0:%.*]] = load double, double* [[D_ADDR]], align 8
+// CHECK-NEXT:[[TMP1:%.*]] = call i32 @llvm.s390.tdc.f64(double [[TMP0]], i64 15) [[ATTR2]]
+// CHECK-NEXT:ret i32 [[TMP1]]
+//
+int test_isnan_double(double d) {
+  return __builtin_isnan(d);
+}
+
+// CHECK-LABEL: @test_isnan_long_double(
+// CHECK-NEXT:  entry:
+// CHECK-NEXT:[[LD_ADDR:%.*]] = alloca fp128, align 8
+// CHECK-NEXT:[[LD:%.*]] = load fp128, fp128* [[TMP0:%.*]], align 8
+// CHECK-NEXT:store fp128 [[LD]], fp128* [[LD_ADDR]], align 8
+// CHECK-NEXT:[[TMP1:%.*]] = load fp128, fp128* [[LD_ADDR]], align 8
+// CHECK-NEXT:[[TMP2:%.*]] = call i32 @llvm.s390.tdc.f128(fp128 [[TMP1]], i64 15) [[ATTR2]]
+// CHECK-NEXT:ret i32 [[TMP2]]
+//
+int test_isnan_long_double(long double ld) {
+  return __builtin_isnan(ld);
+}
+
Index: clang/lib/CodeGen/TargetInfo.h
===
--- clang/lib/CodeGen/TargetInfo.h
+++ clang/lib/CodeGen/TargetInfo.h
@@ -14,6 +14,7 @@
 #ifndef LLVM_CLANG_LIB_CODEGEN_TARGETINFO_H
 #define LLVM_CLANG_LIB_CODEGEN_TARGETINFO_H
 
+#include "CGBuilder.h"
 #include "CodeGenModule.h"
 #include "CGValue.h"
 #include "clang/AST/Type.h"
@@ -126,6 +127,16 @@
 return Address;
   }
 
+  /// Performs a target specific test of a floating point value for things
+  /// like IsNaN, Infinity, ... Nullptr is returned if no implementation
+  /// exists.
+  virtual llvm::Value *
+  testFPKind(llvm::Value *V, unsigned BuiltinID, CGBuilderTy ,
+ CodeGenModule ) const {
+assert(V->getType()->isFloatingPointTy() && "V should have an FP type.");
+return nullptr;
+  }
+
   /// Corrects the low-level LLVM type for a given constraint and "usual"
   /// type.
   ///
Index: clang/lib/CodeGen/TargetInfo.cpp
===
--- clang/lib/CodeGen/TargetInfo.cpp
+++ clang/lib/CodeGen/TargetInfo.cpp
@@ -21,6 +21,7 @@
 #include "clang/AST/RecordLayout.h"
 #include "clang/Basic/CodeGenOptions.h"
 #include "clang/Basic/DiagnosticFrontend.h"
+#include "clang/Basic/Builtins.h"
 #include "clang/CodeGen/CGFunctionInfo.h"
 #include "clang/CodeGen/SwiftCallingConv.h"
 #include "llvm/ADT/SmallBitVector.h"
@@ -30,6 +31,7 @@
 #include "llvm/ADT/Twine.h"
 #include "llvm/IR/DataLayout.h"
 #include "llvm/IR/IntrinsicsNVPTX.h"
+#include "llvm/IR/IntrinsicsS390.h"
 #include "llvm/IR/Type.h"
 #include "llvm/Support/raw_ostream.h"
 #include  // std::sort
@@ -7200,8 +7202,37 @@
   SystemZTargetCodeGenInfo(CodeGenTypes , bool HasVector, bool SoftFloatABI)
   : TargetCodeGenInfo(
 std::make_unique(CGT, HasVector, SoftFloatABI)) {}
-};
 
+  llvm::Value *testFPKind(llvm::Value *V, unsigned BuiltinID,
+  CGBuilderTy ,
+  CodeGenModule ) const override {
+assert(V->getType()->isFloatingPointTy() && "V should have an FP type.");
+// Only use TDC in constrained FP mode.
+if (!Builder.getIsFPConstrained())
+  return nullptr;
+
+llvm::Type *Ty = V->getType();
+if (Ty->isFloatTy() || Ty->isDoubleTy() || Ty->isFP128Ty()) {
+  llvm::Module  = CGM.getModule();
+  auto  = M.getContext();
+  llvm::Function *TDCFunc =
+  llvm::Intrinsic::getDeclaration(, llvm::Intrinsic::s390_tdc, Ty);
+  

[PATCH] D96568: [CFE, SystemZ] Emit s390.tdc instrincic for __builtin_isnan in Constrained FP mode.

2021-02-17 Thread Jonas Paulsson via Phabricator via cfe-commits
jonpa added a comment.

In D96568#2569710 , @thopre wrote:

> In D96568#2569296 , @jonpa wrote:
>
>>> Sounds good to me. Hopefully I'll get round to __builtin_isinf soon and a 
>>> single hook will make the patch slightly smaller.
>>
>> Patch updated to call the new hook testFPKind() and make it take a BuiltinID 
>> as argument (that seems to work at least for the moment - maybe an enum type 
>> will become necessary at some point per your suggestion..?)
>>
>> I am not sure if this is "only" or "typically" used in constrained FP mode, 
>> or if the mode should be independent of calling this hook. The patch as it 
>> is asserts that it is called for an FP type but leaves it to the target to 
>> decide based on the FP mode, where SystemZ opts out unless it is constrained 
>> (which I think is what is wanted...).
>
> LGTM, we can adapt the hook later if needed. I do not know whether allowing 
> the hook to be used for non constrained FP will prove useful but it is easy 
> enough to ignore it for non FP so why not. Thanks for changing that!

Thanks for review!

@uweigand: looks good on the SystemZ parts?


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

https://reviews.llvm.org/D96568

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


[PATCH] D96568: [CFE, SystemZ] Emit s390.tdc instrincic for __builtin_isnan in Constrained FP mode.

2021-02-17 Thread Jonas Paulsson via Phabricator via cfe-commits
jonpa updated this revision to Diff 324376.
jonpa added a comment.

> Sounds good to me. Hopefully I'll get round to __builtin_isinf soon and a 
> single hook will make the patch slightly smaller.

Patch updated to call the new hook testFPKind() and make it take a BuiltinID as 
argument (that seems to work at least for the moment - maybe an enum type will 
become necessary at some point per your suggestion..?)

I am not sure if this is "only" or "typically" used in constrained FP mode, or 
if the mode should be independent of calling this hook. The patch as it is 
asserts that it is called for an FP type but leaves it to the target to decide 
based on the FP mode, where SystemZ opts out unless it is constrained (which I 
think is what is wanted...).


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

https://reviews.llvm.org/D96568

Files:
  clang/lib/CodeGen/CGBuiltin.cpp
  clang/lib/CodeGen/TargetInfo.cpp
  clang/lib/CodeGen/TargetInfo.h
  clang/test/CodeGen/SystemZ/strictfp_builtins.c

Index: clang/test/CodeGen/SystemZ/strictfp_builtins.c
===
--- /dev/null
+++ clang/test/CodeGen/SystemZ/strictfp_builtins.c
@@ -0,0 +1,43 @@
+// NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py
+// REQUIRES: systemz-registered-target
+// RUN: %clang_cc1 %s -emit-llvm -ffp-exception-behavior=maytrap -o - -triple s390x-linux-gnu | FileCheck %s
+
+#pragma float_control(except, on)
+
+// CHECK-LABEL: @test_isnan_float(
+// CHECK-NEXT:  entry:
+// CHECK-NEXT:[[F_ADDR:%.*]] = alloca float, align 4
+// CHECK-NEXT:store float [[F:%.*]], float* [[F_ADDR]], align 4
+// CHECK-NEXT:[[TMP0:%.*]] = load float, float* [[F_ADDR]], align 4
+// CHECK-NEXT:[[TMP1:%.*]] = call i32 @llvm.s390.tdc.f32(float [[TMP0]], i64 15) [[ATTR2:#.*]]
+// CHECK-NEXT:ret i32 [[TMP1]]
+//
+int test_isnan_float(float f) {
+  return __builtin_isnan(f);
+}
+
+// CHECK-LABEL: @test_isnan_double(
+// CHECK-NEXT:  entry:
+// CHECK-NEXT:[[D_ADDR:%.*]] = alloca double, align 8
+// CHECK-NEXT:store double [[D:%.*]], double* [[D_ADDR]], align 8
+// CHECK-NEXT:[[TMP0:%.*]] = load double, double* [[D_ADDR]], align 8
+// CHECK-NEXT:[[TMP1:%.*]] = call i32 @llvm.s390.tdc.f64(double [[TMP0]], i64 15) [[ATTR2]]
+// CHECK-NEXT:ret i32 [[TMP1]]
+//
+int test_isnan_double(double d) {
+  return __builtin_isnan(d);
+}
+
+// CHECK-LABEL: @test_isnan_long_double(
+// CHECK-NEXT:  entry:
+// CHECK-NEXT:[[LD_ADDR:%.*]] = alloca fp128, align 8
+// CHECK-NEXT:[[LD:%.*]] = load fp128, fp128* [[TMP0:%.*]], align 8
+// CHECK-NEXT:store fp128 [[LD]], fp128* [[LD_ADDR]], align 8
+// CHECK-NEXT:[[TMP1:%.*]] = load fp128, fp128* [[LD_ADDR]], align 8
+// CHECK-NEXT:[[TMP2:%.*]] = call i32 @llvm.s390.tdc.f128(fp128 [[TMP1]], i64 15) [[ATTR2]]
+// CHECK-NEXT:ret i32 [[TMP2]]
+//
+int test_isnan_long_double(long double ld) {
+  return __builtin_isnan(ld);
+}
+
Index: clang/lib/CodeGen/TargetInfo.h
===
--- clang/lib/CodeGen/TargetInfo.h
+++ clang/lib/CodeGen/TargetInfo.h
@@ -14,6 +14,7 @@
 #ifndef LLVM_CLANG_LIB_CODEGEN_TARGETINFO_H
 #define LLVM_CLANG_LIB_CODEGEN_TARGETINFO_H
 
+#include "CGBuilder.h"
 #include "CodeGenModule.h"
 #include "CGValue.h"
 #include "clang/AST/Type.h"
@@ -126,6 +127,16 @@
 return Address;
   }
 
+  /// Performs a target specific test of a floating point value for things
+  /// like IsNaN, Infinity, ... Nullptr is returned if no implementation
+  /// exists.
+  virtual llvm::Value *
+  testFPKind(llvm::Value *V, unsigned BuiltinID, CGBuilderTy ,
+ CodeGenModule ) const {
+assert(V->getType()->isFloatingPointTy() && "V should have an FP type.");
+return nullptr;
+  }
+
   /// Corrects the low-level LLVM type for a given constraint and "usual"
   /// type.
   ///
Index: clang/lib/CodeGen/TargetInfo.cpp
===
--- clang/lib/CodeGen/TargetInfo.cpp
+++ clang/lib/CodeGen/TargetInfo.cpp
@@ -21,6 +21,7 @@
 #include "clang/AST/RecordLayout.h"
 #include "clang/Basic/CodeGenOptions.h"
 #include "clang/Basic/DiagnosticFrontend.h"
+#include "clang/Basic/Builtins.h"
 #include "clang/CodeGen/CGFunctionInfo.h"
 #include "clang/CodeGen/SwiftCallingConv.h"
 #include "llvm/ADT/SmallBitVector.h"
@@ -30,6 +31,7 @@
 #include "llvm/ADT/Twine.h"
 #include "llvm/IR/DataLayout.h"
 #include "llvm/IR/IntrinsicsNVPTX.h"
+#include "llvm/IR/IntrinsicsS390.h"
 #include "llvm/IR/Type.h"
 #include "llvm/Support/raw_ostream.h"
 #include  // std::sort
@@ -7200,8 +7202,37 @@
   SystemZTargetCodeGenInfo(CodeGenTypes , bool HasVector, bool SoftFloatABI)
   : TargetCodeGenInfo(
 std::make_unique(CGT, HasVector, SoftFloatABI)) {}
-};
 
+  llvm::Value *testFPKind(llvm::Value *V, unsigned BuiltinID,
+  CGBuilderTy ,
+  CodeGenModule ) 

[PATCH] D96568: [CFE, SystemZ] Emit s390.tdc instrincic for __builtin_isnan in Constrained FP mode.

2021-02-16 Thread Jonas Paulsson via Phabricator via cfe-commits
jonpa added a comment.

In D96568#2559476 , @thopre wrote:

> In D96568#2559475 , @uweigand wrote:
>
>> In D96568#2559336 , @thopre wrote:
>>
>>> That's interesting. I presume that can be used to implement isinf as well? 
>>> Perhaps better call the hook fpclassify or similar?
>>
>> Hmm, the instruction doesn't really implement fpclassify in itself, it is 
>> more like a combined check for fpclassify() == .   
>> Specifically, the TEST DATA CLASS instruction takes an immediate operand 
>> that represents a bit mask, which each bit standing for one type of 
>> floating-point value (zero, normal, subnormal, infinity, QNaN, SNaN -- each 
>> in positive and negative versions).  The instruction sets the condition code 
>> depending on whether the input FP number is in one of the classes selected 
>> by the bit mask, or not.
>>
>> This is why Jonas' patch uses a bit mask of 0x0F -- this has the bits for 
>> the four types of NaN set (pos/neg QNaN/SNan).   The instruction could 
>> indeed also be used to implement an isinf check (bit mask 0x30) or many 
>> other checks.   We actually have a SystemZ back-end pass that tries to 
>> multiple combine FP checks into a single TEST DATA CLASS instruction.
>>
>> However, the instruction does not directly implement the fpclassify 
>> semantics.  To implement fpclassify, you'd still have to use multiple 
>> invocations of the instruction with different flags to determine the 
>> fpclassify output value.
>
> I see. I'm not sure whether it's better to have several target hooks or a 
> single one like testFPKind that would take a flag saying what do we want to 
> test (NaN, Inf, etc.).

Personally I think testFPKind should work well - it gives a single target hook 
for related purposes which should be more readable, and it is also natural for 
SystemZ since we will be using the same (Test Data Class) instruction for 
differnet checks only with different flag bits... Any one else has an opinion? 
Should I go ahead and change the patch to this end?


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

https://reviews.llvm.org/D96568

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


[PATCH] D96471: [SystemZ] Fix vecintrin.h to not emit alignment hints in vec_xl/vec_xst.

2021-02-12 Thread Jonas Paulsson via Phabricator via cfe-commits
jonpa added a comment.

Committed after changed to use __builtin_memcpy() instead.


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D96471

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


[PATCH] D96471: [SystemZ] Fix vecintrin.h to not emit alignment hints in vec_xl/vec_xst.

2021-02-12 Thread Jonas Paulsson via Phabricator via cfe-commits
This revision was not accepted when it landed; it landed in state "Needs 
Review".
This revision was automatically updated to reflect the committed changes.
Closed by commit rGb3ac5b84cdd4: [SystemZ] Fix vecintrin.h to not emit 
alignment hints in vec_xl/vec_xst. (authored by jonpa).
Herald added a project: clang.
Herald added a subscriber: cfe-commits.

Changed prior to commit:
  https://reviews.llvm.org/D96471?vs=322862=323499#toc

Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D96471

Files:
  clang/lib/Headers/vecintrin.h
  clang/test/CodeGen/SystemZ/builtins-systemz-zvector-constrained.c

Index: clang/test/CodeGen/SystemZ/builtins-systemz-zvector-constrained.c
===
--- clang/test/CodeGen/SystemZ/builtins-systemz-zvector-constrained.c
+++ clang/test/CodeGen/SystemZ/builtins-systemz-zvector-constrained.c
@@ -66,16 +66,28 @@
   // CHECK-ASM: vsceg %{{.*}}, 0(%{{.*}},%{{.*}}), 1
 
   vd = vec_xl(idx, cptrd);
-  // CHECK-ASM: vl
+  // CHECK-ASM-NEXT: lgfrl   %r3, idx
+  // CHECK-ASM-NEXT: lgrl%r4, cptrd
+  // CHECK-ASM-NEXT: vl  %v0, 0(%r3,%r4){{$}}
+  // CHECK-ASM-NEXT: vst
 
   vd = vec_xld2(idx, cptrd);
-  // CHECK-ASM: vl
+  // CHECK-ASM-NEXT: lgfrl   %r3, idx
+  // CHECK-ASM-NEXT: lgrl%r4, cptrd
+  // CHECK-ASM-NEXT: vl  %v0, 0(%r3,%r4){{$}}
+  // CHECK-ASM-NEXT: vst
 
   vec_xst(vd, idx, ptrd);
-  // CHECK-ASM: vst
+  // CHECK-ASM-NEXT: vl
+  // CHECK-ASM-NEXT: lgfrl   %r3, idx
+  // CHECK-ASM-NEXT: lgrl%r4, ptrd
+  // CHECK-ASM-NEXT: vst %v0, 0(%r3,%r4){{$}}
 
   vec_xstd2(vd, idx, ptrd);
-  // CHECK-ASM: vst
+  // CHECK-ASM-NEXT: vl
+  // CHECK-ASM-NEXT: lgfrl   %r3, idx
+  // CHECK-ASM-NEXT: lgrl%r4, ptrd
+  // CHECK-ASM-NEXT: vst %v0, 0(%r3,%r4){{$}}
 
   vd = vec_splat(vd, 0);
   // CHECK: shufflevector <2 x double> %{{.*}}, <2 x double> poison, <2 x i32> zeroinitializer
Index: clang/lib/Headers/vecintrin.h
===
--- clang/lib/Headers/vecintrin.h
+++ clang/lib/Headers/vecintrin.h
@@ -1016,64 +1016,84 @@
 
 static inline __ATTRS_o_ai __vector signed char
 vec_xl(long __offset, const signed char *__ptr) {
-  return *(const __vector signed char *)
-  ((const char *)__ptr + __offset);
+  __vector signed char V;
+  __builtin_memcpy(, ((const char *)__ptr + __offset),
+   sizeof(__vector signed char));
+  return V;
 }
 
 static inline __ATTRS_o_ai __vector unsigned char
 vec_xl(long __offset, const unsigned char *__ptr) {
-  return *(const __vector unsigned char *)
-  ((const char *)__ptr + __offset);
+  __vector unsigned char V;
+  __builtin_memcpy(, ((const char *)__ptr + __offset),
+   sizeof(__vector unsigned char));
+  return V;
 }
 
 static inline __ATTRS_o_ai __vector signed short
 vec_xl(long __offset, const signed short *__ptr) {
-  return *(const __vector signed short *)
-  ((const char *)__ptr + __offset);
+  __vector signed short V;
+  __builtin_memcpy(, ((const char *)__ptr + __offset),
+   sizeof(__vector signed short));
+  return V;
 }
 
 static inline __ATTRS_o_ai __vector unsigned short
 vec_xl(long __offset, const unsigned short *__ptr) {
-  return *(const __vector unsigned short *)
-  ((const char *)__ptr + __offset);
+  __vector unsigned short V;
+  __builtin_memcpy(, ((const char *)__ptr + __offset),
+   sizeof(__vector unsigned short));
+  return V;
 }
 
 static inline __ATTRS_o_ai __vector signed int
 vec_xl(long __offset, const signed int *__ptr) {
-  return *(const __vector signed int *)
-  ((const char *)__ptr + __offset);
+  __vector signed int V;
+  __builtin_memcpy(, ((const char *)__ptr + __offset),
+   sizeof(__vector signed int));
+  return V;
 }
 
 static inline __ATTRS_o_ai __vector unsigned int
 vec_xl(long __offset, const unsigned int *__ptr) {
-  return *(const __vector unsigned int *)
-  ((const char *)__ptr + __offset);
+  __vector unsigned int V;
+  __builtin_memcpy(, ((const char *)__ptr + __offset),
+   sizeof(__vector unsigned int));
+  return V;
 }
 
 static inline __ATTRS_o_ai __vector signed long long
 vec_xl(long __offset, const signed long long *__ptr) {
-  return *(const __vector signed long long *)
-  ((const char *)__ptr + __offset);
+  __vector signed long long V;
+  __builtin_memcpy(, ((const char *)__ptr + __offset),
+   sizeof(__vector signed long long));
+  return V;
 }
 
 static inline __ATTRS_o_ai __vector unsigned long long
 vec_xl(long __offset, const unsigned long long *__ptr) {
-  return *(const __vector unsigned long long *)
-  ((const char *)__ptr + __offset);
+  __vector unsigned long long V;
+  __builtin_memcpy(, ((const char *)__ptr + __offset),
+   sizeof(__vector unsigned long long));
+  return V;
 }
 
 #if 

[PATCH] D86844: [LoopDeletion] Allows deletion of possibly infinite side-effect free loops

2020-12-22 Thread Jonas Paulsson via Phabricator via cfe-commits
jonpa added inline comments.



Comment at: llvm/lib/Transforms/Scalar/LoopDeletion.cpp:132
 /// A loop is considered dead if it does not impact the observable behavior of
 /// the program other than finite running time. This never removes a loop that
 /// might be infinite (unless it is never executed), as doing so could change

Seems like it would be nice to update this comment.



Comment at: llvm/lib/Transforms/Scalar/LoopDeletion.cpp:211
   // Don't remove loops for which we can't solve the trip count.
   // They could be infinite, in which case we'd be changing program behavior.
   const SCEV *S = SE.getConstantMaxBackedgeTakenCount(L);

and also this comment..?


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D86844

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


[PATCH] D87279: [clang] Fix handling of physical registers in inline assembly operands.

2020-10-21 Thread Jonas Paulsson via Phabricator via cfe-commits
This revision was automatically updated to reflect the committed changes.
Closed by commit rG42a82862b625: Reapply [clang] Improve handling of 
physical registers in inline (authored by jonpa).

Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D87279

Files:
  clang/lib/CodeGen/CGStmt.cpp
  clang/test/CodeGen/aarch64-inline-asm.c
  clang/test/CodeGen/systemz-inline-asm-02.c
  clang/test/CodeGen/systemz-inline-asm.c

Index: clang/test/CodeGen/systemz-inline-asm.c
===
--- clang/test/CodeGen/systemz-inline-asm.c
+++ clang/test/CodeGen/systemz-inline-asm.c
@@ -129,3 +129,17 @@
 // CHECK: [[RESULT:%.*]] = tail call fp128 asm "axbr $0, $2", "=f,0,f"(fp128 %f, fp128 %g)
 // CHECK: store fp128 [[RESULT]], fp128* [[DEST]]
 }
+
+// Test that there are no tied physreg uses. TwoAddress pass cannot deal with them.
+int test_physregs(void) {
+  // CHECK-LABEL: define signext i32 @test_physregs()
+  register int l __asm__("r7") = 0;
+
+  // CHECK: call i32 asm "lr $0, $1", "={r7},{r7}"
+  __asm__("lr %0, %1" : "+r"(l));
+
+  // CHECK: call i32 asm "$0 $1 $2", "={r7},{r7},{r7}"
+  __asm__("%0 %1 %2" : "+r"(l) : "r"(l));
+
+  return l;
+}
Index: clang/test/CodeGen/systemz-inline-asm-02.c
===
--- /dev/null
+++ clang/test/CodeGen/systemz-inline-asm-02.c
@@ -0,0 +1,13 @@
+// RUN: not %clang_cc1 -triple s390x-linux-gnu -O2 -emit-llvm -o - %s 2>&1 \
+// RUN:  | FileCheck %s
+// REQUIRES: systemz-registered-target
+
+// Test that an error is given if a physreg is defined by multiple operands.
+int test_physreg_defs(void) {
+  register int l __asm__("r7") = 0;
+
+  // CHECK: error: multiple outputs to hard register: r7
+  __asm__("" : "+r"(l), "=r"(l));
+
+  return l;
+}
Index: clang/test/CodeGen/aarch64-inline-asm.c
===
--- clang/test/CodeGen/aarch64-inline-asm.c
+++ clang/test/CodeGen/aarch64-inline-asm.c
@@ -74,3 +74,9 @@
 asm volatile("mov r0, r1\n");
 // CHECK: call void asm sideeffect "mov r0, r1\0A", ""()
 }
+
+void test_tied_earlyclobber(void) {
+  register int a asm("x1");
+  asm("" : "+"(a));
+  // CHECK: call i32 asm "", "=&{x1},0"(i32 %0)
+}
Index: clang/lib/CodeGen/CGStmt.cpp
===
--- clang/lib/CodeGen/CGStmt.cpp
+++ clang/lib/CodeGen/CGStmt.cpp
@@ -21,6 +21,7 @@
 #include "clang/Basic/PrettyStackTrace.h"
 #include "clang/Basic/SourceManager.h"
 #include "clang/Basic/TargetInfo.h"
+#include "llvm/ADT/SmallSet.h"
 #include "llvm/ADT/StringExtras.h"
 #include "llvm/IR/DataLayout.h"
 #include "llvm/IR/InlineAsm.h"
@@ -1953,7 +1954,8 @@
 static std::string
 AddVariableConstraints(const std::string , const Expr ,
const TargetInfo , CodeGenModule ,
-   const AsmStmt , const bool EarlyClobber) {
+   const AsmStmt , const bool EarlyClobber,
+   std::string *GCCReg = nullptr) {
   const DeclRefExpr *AsmDeclRef = dyn_cast();
   if (!AsmDeclRef)
 return Constraint;
@@ -1978,6 +1980,8 @@
   }
   // Canonicalize the register here before returning it.
   Register = Target.getNormalizedGCCRegisterName(Register);
+  if (GCCReg != nullptr)
+*GCCReg = Register.str();
   return (EarlyClobber ? "&{" : "{") + Register.str() + "}";
 }
 
@@ -2176,6 +2180,9 @@
   // Keep track of out constraints for tied input operand.
   std::vector OutputConstraints;
 
+  // Keep track of defined physregs.
+  llvm::SmallSet PhysRegOutputs;
+
   // An inline asm can be marked readonly if it meets the following conditions:
   //  - it doesn't have any sideeffects
   //  - it doesn't clobber memory
@@ -2195,9 +2202,15 @@
 const Expr *OutExpr = S.getOutputExpr(i);
 OutExpr = OutExpr->IgnoreParenNoopCasts(getContext());
 
+std::string GCCReg;
 OutputConstraint = AddVariableConstraints(OutputConstraint, *OutExpr,
   getTarget(), CGM, S,
-  Info.earlyClobber());
+  Info.earlyClobber(),
+  );
+// Give an error on multiple outputs to same physreg.
+if (!GCCReg.empty() && !PhysRegOutputs.insert(GCCReg).second)
+  CGM.Error(S.getAsmLoc(), "multiple outputs to hard register: " + GCCReg);
+
 OutputConstraints.push_back(OutputConstraint);
 LValue Dest = EmitLValue(OutExpr);
 if (!Constraints.empty())
@@ -2284,7 +2297,8 @@
 LargestVectorWidth =
 std::max((uint64_t)LargestVectorWidth,
  VT->getPrimitiveSizeInBits().getKnownMinSize());
-  if (Info.allowsRegister())
+  // Only tie earlyclobber physregs.
+  if (Info.allowsRegister() && (GCCReg.empty() || Info.earlyClobber()))
   

[PATCH] D87279: [clang] Fix handling of physical registers in inline assembly operands.

2020-10-17 Thread Jonas Paulsson via Phabricator via cfe-commits
jonpa updated this revision to Diff 298819.
jonpa added a comment.

Sorry, here's the test case included as well...


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

https://reviews.llvm.org/D87279

Files:
  clang/lib/CodeGen/CGStmt.cpp
  clang/test/CodeGen/aarch64-inline-asm.c
  clang/test/CodeGen/systemz-inline-asm-02.c
  clang/test/CodeGen/systemz-inline-asm.c

Index: clang/test/CodeGen/systemz-inline-asm.c
===
--- clang/test/CodeGen/systemz-inline-asm.c
+++ clang/test/CodeGen/systemz-inline-asm.c
@@ -129,3 +129,17 @@
 // CHECK: [[RESULT:%.*]] = tail call fp128 asm "axbr $0, $2", "=f,0,f"(fp128 %f, fp128 %g)
 // CHECK: store fp128 [[RESULT]], fp128* [[DEST]]
 }
+
+// Test that there are no tied physreg uses. TwoAddress pass cannot deal with them.
+int test_physregs(void) {
+  // CHECK-LABEL: define signext i32 @test_physregs()
+  register int l __asm__("r7") = 0;
+
+  // CHECK: call i32 asm "lr $0, $1", "={r7},{r7}"
+  __asm__("lr %0, %1" : "+r"(l));
+
+  // CHECK: call i32 asm "$0 $1 $2", "={r7},{r7},{r7}"
+  __asm__("%0 %1 %2" : "+r"(l) : "r"(l));
+
+  return l;
+}
Index: clang/test/CodeGen/systemz-inline-asm-02.c
===
--- /dev/null
+++ clang/test/CodeGen/systemz-inline-asm-02.c
@@ -0,0 +1,13 @@
+// RUN: not %clang_cc1 -triple s390x-linux-gnu -O2 -emit-llvm -o - %s 2>&1 \
+// RUN:  | FileCheck %s
+// REQUIRES: systemz-registered-target
+
+// Test that an error is given if a physreg is defined by multiple operands.
+int test_physreg_defs(void) {
+  register int l __asm__("r7") = 0;
+
+  // CHECK: error: multiple outputs to hard register: r7
+  __asm__("" : "+r"(l), "=r"(l));
+
+  return l;
+}
Index: clang/test/CodeGen/aarch64-inline-asm.c
===
--- clang/test/CodeGen/aarch64-inline-asm.c
+++ clang/test/CodeGen/aarch64-inline-asm.c
@@ -74,3 +74,9 @@
 asm volatile("mov r0, r1\n");
 // CHECK: call void asm sideeffect "mov r0, r1\0A", ""()
 }
+
+void test_tied_earlyclobber(void) {
+  register int a asm("x1");
+  asm("" : "+"(a));
+  // CHECK: call i32 asm "", "=&{x1},0"(i32 %0)
+}
Index: clang/lib/CodeGen/CGStmt.cpp
===
--- clang/lib/CodeGen/CGStmt.cpp
+++ clang/lib/CodeGen/CGStmt.cpp
@@ -21,6 +21,7 @@
 #include "clang/Basic/PrettyStackTrace.h"
 #include "clang/Basic/SourceManager.h"
 #include "clang/Basic/TargetInfo.h"
+#include "llvm/ADT/SmallSet.h"
 #include "llvm/ADT/StringExtras.h"
 #include "llvm/IR/DataLayout.h"
 #include "llvm/IR/InlineAsm.h"
@@ -1836,7 +1837,8 @@
 static std::string
 AddVariableConstraints(const std::string , const Expr ,
const TargetInfo , CodeGenModule ,
-   const AsmStmt , const bool EarlyClobber) {
+   const AsmStmt , const bool EarlyClobber,
+   std::string *GCCReg = nullptr) {
   const DeclRefExpr *AsmDeclRef = dyn_cast();
   if (!AsmDeclRef)
 return Constraint;
@@ -1861,6 +1863,8 @@
   }
   // Canonicalize the register here before returning it.
   Register = Target.getNormalizedGCCRegisterName(Register);
+  if (GCCReg != nullptr)
+*GCCReg = Register.str();
   return (EarlyClobber ? "&{" : "{") + Register.str() + "}";
 }
 
@@ -2059,6 +2063,9 @@
   // Keep track of out constraints for tied input operand.
   std::vector OutputConstraints;
 
+  // Keep track of defined physregs.
+  llvm::SmallSet PhysRegOutputs;
+
   // An inline asm can be marked readonly if it meets the following conditions:
   //  - it doesn't have any sideeffects
   //  - it doesn't clobber memory
@@ -2078,9 +2085,15 @@
 const Expr *OutExpr = S.getOutputExpr(i);
 OutExpr = OutExpr->IgnoreParenNoopCasts(getContext());
 
+std::string GCCReg;
 OutputConstraint = AddVariableConstraints(OutputConstraint, *OutExpr,
   getTarget(), CGM, S,
-  Info.earlyClobber());
+  Info.earlyClobber(),
+  );
+// Give an error on multiple outputs to same physreg.
+if (!GCCReg.empty() && !PhysRegOutputs.insert(GCCReg).second)
+  CGM.Error(S.getAsmLoc(), "multiple outputs to hard register: " + GCCReg);
+
 OutputConstraints.push_back(OutputConstraint);
 LValue Dest = EmitLValue(OutExpr);
 if (!Constraints.empty())
@@ -2167,7 +2180,8 @@
 LargestVectorWidth =
 std::max((uint64_t)LargestVectorWidth,
  VT->getPrimitiveSizeInBits().getKnownMinSize());
-  if (Info.allowsRegister())
+  // Only tie earlyclobber physregs.
+  if (Info.allowsRegister() && (GCCReg.empty() || Info.earlyClobber()))
 InOutConstraints += llvm::utostr(i);
   else
 InOutConstraints += OutputConstraint;

[PATCH] D87279: [clang] Fix handling of physical registers in inline assembly operands.

2020-10-16 Thread Jonas Paulsson via Phabricator via cfe-commits
jonpa updated this revision to Diff 298624.
jonpa added a comment.

That makes sense... Patch updated to keep the tying of operands for this case 
of earlyclobber.

@nickdesaulniers : Can you see if this patch now passes your builds?


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

https://reviews.llvm.org/D87279

Files:
  clang/lib/CodeGen/CGStmt.cpp
  clang/test/CodeGen/systemz-inline-asm-02.c
  clang/test/CodeGen/systemz-inline-asm.c

Index: clang/test/CodeGen/systemz-inline-asm.c
===
--- clang/test/CodeGen/systemz-inline-asm.c
+++ clang/test/CodeGen/systemz-inline-asm.c
@@ -129,3 +129,17 @@
 // CHECK: [[RESULT:%.*]] = tail call fp128 asm "axbr $0, $2", "=f,0,f"(fp128 %f, fp128 %g)
 // CHECK: store fp128 [[RESULT]], fp128* [[DEST]]
 }
+
+// Test that there are no tied physreg uses. TwoAddress pass cannot deal with them.
+int test_physregs(void) {
+  // CHECK-LABEL: define signext i32 @test_physregs()
+  register int l __asm__("r7") = 0;
+
+  // CHECK: call i32 asm "lr $0, $1", "={r7},{r7}"
+  __asm__("lr %0, %1" : "+r"(l));
+
+  // CHECK: call i32 asm "$0 $1 $2", "={r7},{r7},{r7}"
+  __asm__("%0 %1 %2" : "+r"(l) : "r"(l));
+
+  return l;
+}
Index: clang/test/CodeGen/systemz-inline-asm-02.c
===
--- /dev/null
+++ clang/test/CodeGen/systemz-inline-asm-02.c
@@ -0,0 +1,13 @@
+// RUN: not %clang_cc1 -triple s390x-linux-gnu -O2 -emit-llvm -o - %s 2>&1 \
+// RUN:  | FileCheck %s
+// REQUIRES: systemz-registered-target
+
+// Test that an error is given if a physreg is defined by multiple operands.
+int test_physreg_defs(void) {
+  register int l __asm__("r7") = 0;
+
+  // CHECK: error: multiple outputs to hard register: r7
+  __asm__("" : "+r"(l), "=r"(l));
+
+  return l;
+}
Index: clang/lib/CodeGen/CGStmt.cpp
===
--- clang/lib/CodeGen/CGStmt.cpp
+++ clang/lib/CodeGen/CGStmt.cpp
@@ -21,6 +21,7 @@
 #include "clang/Basic/PrettyStackTrace.h"
 #include "clang/Basic/SourceManager.h"
 #include "clang/Basic/TargetInfo.h"
+#include "llvm/ADT/SmallSet.h"
 #include "llvm/ADT/StringExtras.h"
 #include "llvm/IR/DataLayout.h"
 #include "llvm/IR/InlineAsm.h"
@@ -1836,7 +1837,8 @@
 static std::string
 AddVariableConstraints(const std::string , const Expr ,
const TargetInfo , CodeGenModule ,
-   const AsmStmt , const bool EarlyClobber) {
+   const AsmStmt , const bool EarlyClobber,
+   std::string *GCCReg = nullptr) {
   const DeclRefExpr *AsmDeclRef = dyn_cast();
   if (!AsmDeclRef)
 return Constraint;
@@ -1861,6 +1863,8 @@
   }
   // Canonicalize the register here before returning it.
   Register = Target.getNormalizedGCCRegisterName(Register);
+  if (GCCReg != nullptr)
+*GCCReg = Register.str();
   return (EarlyClobber ? "&{" : "{") + Register.str() + "}";
 }
 
@@ -2059,6 +2063,9 @@
   // Keep track of out constraints for tied input operand.
   std::vector OutputConstraints;
 
+  // Keep track of defined physregs.
+  llvm::SmallSet PhysRegOutputs;
+
   // An inline asm can be marked readonly if it meets the following conditions:
   //  - it doesn't have any sideeffects
   //  - it doesn't clobber memory
@@ -2078,9 +2085,15 @@
 const Expr *OutExpr = S.getOutputExpr(i);
 OutExpr = OutExpr->IgnoreParenNoopCasts(getContext());
 
+std::string GCCReg;
 OutputConstraint = AddVariableConstraints(OutputConstraint, *OutExpr,
   getTarget(), CGM, S,
-  Info.earlyClobber());
+  Info.earlyClobber(),
+  );
+// Give an error on multiple outputs to same physreg.
+if (!GCCReg.empty() && !PhysRegOutputs.insert(GCCReg).second)
+  CGM.Error(S.getAsmLoc(), "multiple outputs to hard register: " + GCCReg);
+
 OutputConstraints.push_back(OutputConstraint);
 LValue Dest = EmitLValue(OutExpr);
 if (!Constraints.empty())
@@ -2167,7 +2180,8 @@
 LargestVectorWidth =
 std::max((uint64_t)LargestVectorWidth,
  VT->getPrimitiveSizeInBits().getKnownMinSize());
-  if (Info.allowsRegister())
+  // Only tie earlyclobber physregs.
+  if (Info.allowsRegister() && (GCCReg.empty() || Info.earlyClobber()))
 InOutConstraints += llvm::utostr(i);
   else
 InOutConstraints += OutputConstraint;
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D87279: [clang] Fix handling of physical registers in inline assembly operands.

2020-10-16 Thread Jonas Paulsson via Phabricator via cfe-commits
jonpa added a comment.

The problem seems to be with a tied earlyclobber operand:

  asm("" : "+"(a));

Per the comment in InlineAsm::ConstraintInfo::Parse(), only output can be 
earlyclobber.

I am not sure if the earlyclobber ('&') should with this patch be removed from 
the added use of the register, or if this has to for some reason really be tied 
to the def?


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D87279

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


[PATCH] D87279: [clang] Fix handling of physical registers in inline assembly operands.

2020-10-14 Thread Jonas Paulsson via Phabricator via cfe-commits
jonpa reopened this revision.
jonpa added a comment.
This revision is now accepted and ready to land.

Patch temporarily reverted.


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D87279

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


[PATCH] D87279: [clang] Fix handling of physical registers in inline assembly operands.

2020-10-13 Thread Jonas Paulsson via Phabricator via cfe-commits
This revision was automatically updated to reflect the committed changes.
Closed by commit rGc78da037783b: [clang] Improve handling of physical registers 
in inline assembly operands. (authored by jonpa).
Herald added a project: clang.

Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D87279

Files:
  clang/lib/CodeGen/CGStmt.cpp
  clang/test/CodeGen/systemz-inline-asm-02.c
  clang/test/CodeGen/systemz-inline-asm.c

Index: clang/test/CodeGen/systemz-inline-asm.c
===
--- clang/test/CodeGen/systemz-inline-asm.c
+++ clang/test/CodeGen/systemz-inline-asm.c
@@ -129,3 +129,17 @@
 // CHECK: [[RESULT:%.*]] = tail call fp128 asm "axbr $0, $2", "=f,0,f"(fp128 %f, fp128 %g)
 // CHECK: store fp128 [[RESULT]], fp128* [[DEST]]
 }
+
+// Test that there are no tied physreg uses. TwoAddress pass cannot deal with them.
+int test_physregs(void) {
+  // CHECK-LABEL: define signext i32 @test_physregs()
+  register int l __asm__("r7") = 0;
+
+  // CHECK: call i32 asm "lr $0, $1", "={r7},{r7}"
+  __asm__("lr %0, %1" : "+r"(l));
+
+  // CHECK: call i32 asm "$0 $1 $2", "={r7},{r7},{r7}"
+  __asm__("%0 %1 %2" : "+r"(l) : "r"(l));
+
+  return l;
+}
Index: clang/test/CodeGen/systemz-inline-asm-02.c
===
--- /dev/null
+++ clang/test/CodeGen/systemz-inline-asm-02.c
@@ -0,0 +1,13 @@
+// RUN: not %clang_cc1 -triple s390x-linux-gnu -O2 -emit-llvm -o - %s 2>&1 \
+// RUN:  | FileCheck %s
+// REQUIRES: systemz-registered-target
+
+// Test that an error is given if a physreg is defined by multiple operands.
+int test_physreg_defs(void) {
+  register int l __asm__("r7") = 0;
+
+  // CHECK: error: multiple outputs to hard register: r7
+  __asm__("" : "+r"(l), "=r"(l));
+
+  return l;
+}
Index: clang/lib/CodeGen/CGStmt.cpp
===
--- clang/lib/CodeGen/CGStmt.cpp
+++ clang/lib/CodeGen/CGStmt.cpp
@@ -21,6 +21,7 @@
 #include "clang/Basic/PrettyStackTrace.h"
 #include "clang/Basic/SourceManager.h"
 #include "clang/Basic/TargetInfo.h"
+#include "llvm/ADT/SmallSet.h"
 #include "llvm/ADT/StringExtras.h"
 #include "llvm/IR/DataLayout.h"
 #include "llvm/IR/InlineAsm.h"
@@ -1836,7 +1837,8 @@
 static std::string
 AddVariableConstraints(const std::string , const Expr ,
const TargetInfo , CodeGenModule ,
-   const AsmStmt , const bool EarlyClobber) {
+   const AsmStmt , const bool EarlyClobber,
+   std::string *GCCReg = nullptr) {
   const DeclRefExpr *AsmDeclRef = dyn_cast();
   if (!AsmDeclRef)
 return Constraint;
@@ -1861,6 +1863,8 @@
   }
   // Canonicalize the register here before returning it.
   Register = Target.getNormalizedGCCRegisterName(Register);
+  if (GCCReg != nullptr)
+*GCCReg = Register.str();
   return (EarlyClobber ? "&{" : "{") + Register.str() + "}";
 }
 
@@ -2059,6 +2063,9 @@
   // Keep track of out constraints for tied input operand.
   std::vector OutputConstraints;
 
+  // Keep track of defined physregs.
+  llvm::SmallSet PhysRegOutputs;
+
   // An inline asm can be marked readonly if it meets the following conditions:
   //  - it doesn't have any sideeffects
   //  - it doesn't clobber memory
@@ -2078,9 +2085,15 @@
 const Expr *OutExpr = S.getOutputExpr(i);
 OutExpr = OutExpr->IgnoreParenNoopCasts(getContext());
 
+std::string GCCReg;
 OutputConstraint = AddVariableConstraints(OutputConstraint, *OutExpr,
   getTarget(), CGM, S,
-  Info.earlyClobber());
+  Info.earlyClobber(),
+  );
+// Give an error on multiple outputs to same physreg.
+if (!GCCReg.empty() && !PhysRegOutputs.insert(GCCReg).second)
+  CGM.Error(S.getAsmLoc(), "multiple outputs to hard register: " + GCCReg);
+
 OutputConstraints.push_back(OutputConstraint);
 LValue Dest = EmitLValue(OutExpr);
 if (!Constraints.empty())
@@ -2167,7 +2180,8 @@
 LargestVectorWidth =
 std::max((uint64_t)LargestVectorWidth,
  VT->getPrimitiveSizeInBits().getKnownMinSize());
-  if (Info.allowsRegister())
+  // Don't tie physregs.
+  if (Info.allowsRegister() && GCCReg.empty())
 InOutConstraints += llvm::utostr(i);
   else
 InOutConstraints += OutputConstraint;
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D87279: [clang] Fix handling of physical registers in inline assembly operands.

2020-10-09 Thread Jonas Paulsson via Phabricator via cfe-commits
jonpa updated this revision to Diff 297136.
jonpa marked an inline comment as done.
jonpa added a comment.

Updated message string per review.


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

https://reviews.llvm.org/D87279

Files:
  clang/lib/CodeGen/CGStmt.cpp
  clang/test/CodeGen/systemz-inline-asm-02.c
  clang/test/CodeGen/systemz-inline-asm.c

Index: clang/test/CodeGen/systemz-inline-asm.c
===
--- clang/test/CodeGen/systemz-inline-asm.c
+++ clang/test/CodeGen/systemz-inline-asm.c
@@ -129,3 +129,17 @@
 // CHECK: [[RESULT:%.*]] = tail call fp128 asm "axbr $0, $2", "=f,0,f"(fp128 %f, fp128 %g)
 // CHECK: store fp128 [[RESULT]], fp128* [[DEST]]
 }
+
+// Test that there are no tied physreg uses. TwoAddress pass cannot deal with them.
+int test_physregs(void) {
+  // CHECK-LABEL: define signext i32 @test_physregs()
+  register int l __asm__("r7") = 0;
+
+  // CHECK: call i32 asm "lr $0, $1", "={r7},{r7}"
+  __asm__("lr %0, %1" : "+r"(l));
+
+  // CHECK: call i32 asm "$0 $1 $2", "={r7},{r7},{r7}"
+  __asm__("%0 %1 %2" : "+r"(l) : "r"(l));
+
+  return l;
+}
Index: clang/test/CodeGen/systemz-inline-asm-02.c
===
--- /dev/null
+++ clang/test/CodeGen/systemz-inline-asm-02.c
@@ -0,0 +1,13 @@
+// RUN: not %clang_cc1 -triple s390x-linux-gnu -O2 -emit-llvm -o - %s 2>&1 \
+// RUN:  | FileCheck %s
+// REQUIRES: systemz-registered-target
+
+// Test that an error is given if a physreg is defined by multiple operands.
+int test_physreg_defs(void) {
+  register int l __asm__("r7") = 0;
+
+  // CHECK: error: multiple outputs to hard register: r7
+  __asm__("" : "+r"(l), "=r"(l));
+
+  return l;
+}
Index: clang/lib/CodeGen/CGStmt.cpp
===
--- clang/lib/CodeGen/CGStmt.cpp
+++ clang/lib/CodeGen/CGStmt.cpp
@@ -21,6 +21,7 @@
 #include "clang/Basic/PrettyStackTrace.h"
 #include "clang/Basic/SourceManager.h"
 #include "clang/Basic/TargetInfo.h"
+#include "llvm/ADT/SmallSet.h"
 #include "llvm/ADT/StringExtras.h"
 #include "llvm/IR/DataLayout.h"
 #include "llvm/IR/InlineAsm.h"
@@ -1836,7 +1837,8 @@
 static std::string
 AddVariableConstraints(const std::string , const Expr ,
const TargetInfo , CodeGenModule ,
-   const AsmStmt , const bool EarlyClobber) {
+   const AsmStmt , const bool EarlyClobber,
+   std::string *GCCReg = nullptr) {
   const DeclRefExpr *AsmDeclRef = dyn_cast();
   if (!AsmDeclRef)
 return Constraint;
@@ -1861,6 +1863,8 @@
   }
   // Canonicalize the register here before returning it.
   Register = Target.getNormalizedGCCRegisterName(Register);
+  if (GCCReg != nullptr)
+*GCCReg = Register.str();
   return (EarlyClobber ? "&{" : "{") + Register.str() + "}";
 }
 
@@ -2059,6 +2063,9 @@
   // Keep track of out constraints for tied input operand.
   std::vector OutputConstraints;
 
+  // Keep track of defined physregs.
+  llvm::SmallSet PhysRegOutputs;
+
   // An inline asm can be marked readonly if it meets the following conditions:
   //  - it doesn't have any sideeffects
   //  - it doesn't clobber memory
@@ -2078,9 +2085,15 @@
 const Expr *OutExpr = S.getOutputExpr(i);
 OutExpr = OutExpr->IgnoreParenNoopCasts(getContext());
 
+std::string GCCReg;
 OutputConstraint = AddVariableConstraints(OutputConstraint, *OutExpr,
   getTarget(), CGM, S,
-  Info.earlyClobber());
+  Info.earlyClobber(),
+  );
+// Give an error on multiple outputs to same physreg.
+if (!GCCReg.empty() && !PhysRegOutputs.insert(GCCReg).second)
+  CGM.Error(S.getAsmLoc(), "multiple outputs to hard register: " + GCCReg);
+
 OutputConstraints.push_back(OutputConstraint);
 LValue Dest = EmitLValue(OutExpr);
 if (!Constraints.empty())
@@ -2167,7 +2180,8 @@
 LargestVectorWidth =
 std::max((uint64_t)LargestVectorWidth,
  VT->getPrimitiveSizeInBits().getKnownMinSize());
-  if (Info.allowsRegister())
+  // Don't tie physregs.
+  if (Info.allowsRegister() && GCCReg.empty())
 InOutConstraints += llvm::utostr(i);
   else
 InOutConstraints += OutputConstraint;
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D87279: [clang] Fix handling of physical registers in inline assembly operands.

2020-10-08 Thread Jonas Paulsson via Phabricator via cfe-commits
jonpa updated this revision to Diff 296901.
jonpa marked an inline comment as done.
jonpa added a comment.

Updated per review to use SmallSet.


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

https://reviews.llvm.org/D87279

Files:
  clang/lib/CodeGen/CGStmt.cpp
  clang/test/CodeGen/systemz-inline-asm-02.c
  clang/test/CodeGen/systemz-inline-asm.c

Index: clang/test/CodeGen/systemz-inline-asm.c
===
--- clang/test/CodeGen/systemz-inline-asm.c
+++ clang/test/CodeGen/systemz-inline-asm.c
@@ -129,3 +129,17 @@
 // CHECK: [[RESULT:%.*]] = tail call fp128 asm "axbr $0, $2", "=f,0,f"(fp128 %f, fp128 %g)
 // CHECK: store fp128 [[RESULT]], fp128* [[DEST]]
 }
+
+// Test that there are no tied physreg uses. TwoAddress pass cannot deal with them.
+int test_physregs(void) {
+  // CHECK-LABEL: define signext i32 @test_physregs()
+  register int l __asm__("r7") = 0;
+
+  // CHECK: call i32 asm "lr $0, $1", "={r7},{r7}"
+  __asm__("lr %0, %1" : "+r"(l));
+
+  // CHECK: call i32 asm "$0 $1 $2", "={r7},{r7},{r7}"
+  __asm__("%0 %1 %2" : "+r"(l) : "r"(l));
+
+  return l;
+}
Index: clang/test/CodeGen/systemz-inline-asm-02.c
===
--- /dev/null
+++ clang/test/CodeGen/systemz-inline-asm-02.c
@@ -0,0 +1,13 @@
+// RUN: not %clang_cc1 -triple s390x-linux-gnu -O2 -emit-llvm -o - %s 2>&1 \
+// RUN:  | FileCheck %s
+// REQUIRES: systemz-registered-target
+
+// Test that an error is given if a physreg is defined by multiple operands.
+int test_physreg_defs(void) {
+  register int l __asm__("r7") = 0;
+
+  // CHECK: error: Multiple outputs to hard register: r7
+  __asm__("" : "+r"(l), "=r"(l));
+
+  return l;
+}
Index: clang/lib/CodeGen/CGStmt.cpp
===
--- clang/lib/CodeGen/CGStmt.cpp
+++ clang/lib/CodeGen/CGStmt.cpp
@@ -21,6 +21,7 @@
 #include "clang/Basic/PrettyStackTrace.h"
 #include "clang/Basic/SourceManager.h"
 #include "clang/Basic/TargetInfo.h"
+#include "llvm/ADT/SmallSet.h"
 #include "llvm/ADT/StringExtras.h"
 #include "llvm/IR/DataLayout.h"
 #include "llvm/IR/InlineAsm.h"
@@ -1836,7 +1837,8 @@
 static std::string
 AddVariableConstraints(const std::string , const Expr ,
const TargetInfo , CodeGenModule ,
-   const AsmStmt , const bool EarlyClobber) {
+   const AsmStmt , const bool EarlyClobber,
+   std::string *GCCReg = nullptr) {
   const DeclRefExpr *AsmDeclRef = dyn_cast();
   if (!AsmDeclRef)
 return Constraint;
@@ -1861,6 +1863,8 @@
   }
   // Canonicalize the register here before returning it.
   Register = Target.getNormalizedGCCRegisterName(Register);
+  if (GCCReg != nullptr)
+*GCCReg = Register.str();
   return (EarlyClobber ? "&{" : "{") + Register.str() + "}";
 }
 
@@ -2059,6 +2063,9 @@
   // Keep track of out constraints for tied input operand.
   std::vector OutputConstraints;
 
+  // Keep track of defined physregs.
+  llvm::SmallSet PhysRegOutputs;
+
   // An inline asm can be marked readonly if it meets the following conditions:
   //  - it doesn't have any sideeffects
   //  - it doesn't clobber memory
@@ -2078,9 +2085,15 @@
 const Expr *OutExpr = S.getOutputExpr(i);
 OutExpr = OutExpr->IgnoreParenNoopCasts(getContext());
 
+std::string GCCReg;
 OutputConstraint = AddVariableConstraints(OutputConstraint, *OutExpr,
   getTarget(), CGM, S,
-  Info.earlyClobber());
+  Info.earlyClobber(),
+  );
+// Give an error on multiple outputs to same physreg.
+if (!GCCReg.empty() && !PhysRegOutputs.insert(GCCReg).second)
+  CGM.Error(S.getAsmLoc(), "Multiple outputs to hard register: " + GCCReg);
+
 OutputConstraints.push_back(OutputConstraint);
 LValue Dest = EmitLValue(OutExpr);
 if (!Constraints.empty())
@@ -2167,7 +2180,8 @@
 LargestVectorWidth =
 std::max((uint64_t)LargestVectorWidth,
  VT->getPrimitiveSizeInBits().getKnownMinSize());
-  if (Info.allowsRegister())
+  // Don't tie physregs.
+  if (Info.allowsRegister() && GCCReg.empty())
 InOutConstraints += llvm::utostr(i);
   else
 InOutConstraints += OutputConstraint;
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D87279: [clang] Fix handling of physical registers in inline assembly operands.

2020-10-07 Thread Jonas Paulsson via Phabricator via cfe-commits
jonpa added inline comments.



Comment at: clang/lib/CodeGen/CGStmt.cpp:2090
+CGM.Error(S.getAsmLoc(), "Multiple outputs to hard register: " + 
GCCReg);
+  PhysRegOutputs.insert(GCCReg);
+}

craig.topper wrote:
> Can we get rid of the count call above and just use the bool from the 
> std::pair returned by insert?
Ah, yes.



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

https://reviews.llvm.org/D87279

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


[PATCH] D87279: [clang] Fix handling of physical registers in inline assembly operands.

2020-10-07 Thread Jonas Paulsson via Phabricator via cfe-commits
jonpa updated this revision to Diff 296618.
jonpa marked an inline comment as done.
jonpa added a comment.

Updated per review by eliminating the call to 'count'.


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

https://reviews.llvm.org/D87279

Files:
  clang/lib/CodeGen/CGStmt.cpp
  clang/test/CodeGen/systemz-inline-asm-02.c
  clang/test/CodeGen/systemz-inline-asm.c


Index: clang/test/CodeGen/systemz-inline-asm.c
===
--- clang/test/CodeGen/systemz-inline-asm.c
+++ clang/test/CodeGen/systemz-inline-asm.c
@@ -129,3 +129,17 @@
 // CHECK: [[RESULT:%.*]] = tail call fp128 asm "axbr $0, $2", "=f,0,f"(fp128 
%f, fp128 %g)
 // CHECK: store fp128 [[RESULT]], fp128* [[DEST]]
 }
+
+// Test that there are no tied physreg uses. TwoAddress pass cannot deal with 
them.
+int test_physregs(void) {
+  // CHECK-LABEL: define signext i32 @test_physregs()
+  register int l __asm__("r7") = 0;
+
+  // CHECK: call i32 asm "lr $0, $1", "={r7},{r7}"
+  __asm__("lr %0, %1" : "+r"(l));
+
+  // CHECK: call i32 asm "$0 $1 $2", "={r7},{r7},{r7}"
+  __asm__("%0 %1 %2" : "+r"(l) : "r"(l));
+
+  return l;
+}
Index: clang/test/CodeGen/systemz-inline-asm-02.c
===
--- /dev/null
+++ clang/test/CodeGen/systemz-inline-asm-02.c
@@ -0,0 +1,13 @@
+// RUN: not %clang_cc1 -triple s390x-linux-gnu -O2 -emit-llvm -o - %s 2>&1 \
+// RUN:  | FileCheck %s
+// REQUIRES: systemz-registered-target
+
+// Test that an error is given if a physreg is defined by multiple operands.
+int test_physreg_defs(void) {
+  register int l __asm__("r7") = 0;
+
+  // CHECK: error: Multiple outputs to hard register: r7
+  __asm__("" : "+r"(l), "=r"(l));
+
+  return l;
+}
Index: clang/lib/CodeGen/CGStmt.cpp
===
--- clang/lib/CodeGen/CGStmt.cpp
+++ clang/lib/CodeGen/CGStmt.cpp
@@ -1836,7 +1836,8 @@
 static std::string
 AddVariableConstraints(const std::string , const Expr ,
const TargetInfo , CodeGenModule ,
-   const AsmStmt , const bool EarlyClobber) {
+   const AsmStmt , const bool EarlyClobber,
+   std::string *GCCReg = nullptr) {
   const DeclRefExpr *AsmDeclRef = dyn_cast();
   if (!AsmDeclRef)
 return Constraint;
@@ -1861,6 +1862,8 @@
   }
   // Canonicalize the register here before returning it.
   Register = Target.getNormalizedGCCRegisterName(Register);
+  if (GCCReg != nullptr)
+*GCCReg = Register.str();
   return (EarlyClobber ? "&{" : "{") + Register.str() + "}";
 }
 
@@ -2059,6 +2062,9 @@
   // Keep track of out constraints for tied input operand.
   std::vector OutputConstraints;
 
+  // Keep track of defined physregs.
+  std::set PhysRegOutputs;
+
   // An inline asm can be marked readonly if it meets the following conditions:
   //  - it doesn't have any sideeffects
   //  - it doesn't clobber memory
@@ -2078,9 +2084,15 @@
 const Expr *OutExpr = S.getOutputExpr(i);
 OutExpr = OutExpr->IgnoreParenNoopCasts(getContext());
 
+std::string GCCReg;
 OutputConstraint = AddVariableConstraints(OutputConstraint, *OutExpr,
   getTarget(), CGM, S,
-  Info.earlyClobber());
+  Info.earlyClobber(),
+  );
+// Give an error on multiple outputs to same physreg.
+if (!GCCReg.empty() && !PhysRegOutputs.insert(GCCReg).second)
+  CGM.Error(S.getAsmLoc(), "Multiple outputs to hard register: " + GCCReg);
+
 OutputConstraints.push_back(OutputConstraint);
 LValue Dest = EmitLValue(OutExpr);
 if (!Constraints.empty())
@@ -2167,7 +2179,8 @@
 LargestVectorWidth =
 std::max((uint64_t)LargestVectorWidth,
  VT->getPrimitiveSizeInBits().getKnownMinSize());
-  if (Info.allowsRegister())
+  // Don't tie physregs.
+  if (Info.allowsRegister() && GCCReg.empty())
 InOutConstraints += llvm::utostr(i);
   else
 InOutConstraints += OutputConstraint;


Index: clang/test/CodeGen/systemz-inline-asm.c
===
--- clang/test/CodeGen/systemz-inline-asm.c
+++ clang/test/CodeGen/systemz-inline-asm.c
@@ -129,3 +129,17 @@
 // CHECK: [[RESULT:%.*]] = tail call fp128 asm "axbr $0, $2", "=f,0,f"(fp128 %f, fp128 %g)
 // CHECK: store fp128 [[RESULT]], fp128* [[DEST]]
 }
+
+// Test that there are no tied physreg uses. TwoAddress pass cannot deal with them.
+int test_physregs(void) {
+  // CHECK-LABEL: define signext i32 @test_physregs()
+  register int l __asm__("r7") = 0;
+
+  // CHECK: call i32 asm "lr $0, $1", "={r7},{r7}"
+  __asm__("lr %0, %1" : "+r"(l));
+
+  // CHECK: call i32 asm "$0 $1 $2", "={r7},{r7},{r7}"
+  __asm__("%0 %1 %2" : "+r"(l) : "r"(l));
+
+  return l;
+}

[PATCH] D87279: [clang] Fix handling of physical registers in inline assembly operands.

2020-10-06 Thread Jonas Paulsson via Phabricator via cfe-commits
jonpa added reviewers: RKSimon, jyu2, t.p.northover, echristo, dylanmckay, 
aaron.ballman.
jonpa added a comment.
Herald added a subscriber: pengfei.

Ping!

Last chance for anyone to speak up about any objections to committing this...


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

https://reviews.llvm.org/D87279

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


[PATCH] D87279: [clang] Fix handling of physical registers in inline assembly operands.

2020-09-28 Thread Jonas Paulsson via Phabricator via cfe-commits
jonpa added a comment.

ping!


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

https://reviews.llvm.org/D87279

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


[PATCH] D87279: [clang] Fix handling of physical registers in inline assembly operands.

2020-09-22 Thread Jonas Paulsson via Phabricator via cfe-commits
jonpa added a comment.

ping!


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

https://reviews.llvm.org/D87279

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


[PATCH] D78717: [SystemZ] Implement -fstack-clash-protection

2020-06-06 Thread Jonas Paulsson via Phabricator via cfe-commits
This revision was automatically updated to reflect the committed changes.
jonpa marked an inline comment as done.
Closed by commit rG515bfc66eace (authored by jonpa).
Herald added a project: clang.
Herald added a subscriber: cfe-commits.

Changed prior to commit:
  https://reviews.llvm.org/D78717?vs=268419=269023#toc

Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D78717

Files:
  clang/docs/ReleaseNotes.rst
  clang/lib/Basic/Targets/SystemZ.h
  clang/lib/Driver/ToolChains/Clang.cpp
  clang/test/CodeGen/stack-clash-protection.c
  clang/test/Driver/stack-clash-protection-02.c
  llvm/include/llvm/ADT/Triple.h
  llvm/lib/Target/SystemZ/SystemZFrameLowering.cpp
  llvm/lib/Target/SystemZ/SystemZFrameLowering.h
  llvm/lib/Target/SystemZ/SystemZISelLowering.cpp
  llvm/lib/Target/SystemZ/SystemZISelLowering.h
  llvm/lib/Target/SystemZ/SystemZInstrInfo.cpp
  llvm/lib/Target/SystemZ/SystemZInstrInfo.h
  llvm/lib/Target/SystemZ/SystemZInstrInfo.td
  llvm/lib/Target/SystemZ/SystemZOperators.td
  llvm/test/CodeGen/SystemZ/stack-clash-dynamic-alloca.ll
  llvm/test/CodeGen/SystemZ/stack-clash-protection.ll

Index: llvm/test/CodeGen/SystemZ/stack-clash-protection.ll
===
--- /dev/null
+++ llvm/test/CodeGen/SystemZ/stack-clash-protection.ll
@@ -0,0 +1,242 @@
+; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
+; RUN: llc < %s -mtriple=s390x-linux-gnu -mcpu=z14 -O3 | FileCheck %s
+;
+; Test stack clash protection probing for static allocas.
+
+; Small: one probe.
+define i32 @fun0() #0 {
+; CHECK-LABEL: fun0:
+; CHECK:   # %bb.0:
+; CHECK-NEXT:aghi %r15, -560
+; CHECK-NEXT:.cfi_def_cfa_offset 720
+; CHECK-NEXT:cg %r0, 552(%r15)
+; CHECK-NEXT:mvhi 552(%r15), 1
+; CHECK-NEXT:l %r2, 160(%r15)
+; CHECK-NEXT:aghi %r15, 560
+; CHECK-NEXT:br %r14
+
+  %a = alloca i32, i64 100
+  %b = getelementptr inbounds i32, i32* %a, i64 98
+  store volatile i32 1, i32* %b
+  %c = load volatile i32, i32* %a
+  ret i32 %c
+}
+
+; Medium: two probes.
+define i32 @fun1() #0 {
+; CHECK-LABEL: fun1:
+; CHECK:   # %bb.0:
+; CHECK-NEXT:aghi %r15, -4096
+; CHECK-NEXT:.cfi_def_cfa_offset 4256
+; CHECK-NEXT:cg %r0, 4088(%r15)
+; CHECK-NEXT:aghi %r15, -4080
+; CHECK-NEXT:.cfi_def_cfa_offset 8336
+; CHECK-NEXT:cg %r0, 4072(%r15)
+; CHECK-NEXT:mvhi 976(%r15), 1
+; CHECK-NEXT:l %r2, 176(%r15)
+; CHECK-NEXT:aghi %r15, 8176
+; CHECK-NEXT:br %r14
+
+  %a = alloca i32, i64 2000
+  %b = getelementptr inbounds i32, i32* %a, i64 200
+  store volatile i32 1, i32* %b
+  %c = load volatile i32, i32* %a
+  ret i32 %c
+}
+
+; Large: Use a loop to allocate and probe in steps.
+define i32 @fun2() #0 {
+; CHECK-LABEL: fun2:
+; CHECK:   # %bb.0:
+; CHECK-NEXT:lgr %r1, %r15
+; CHECK-NEXT:.cfi_def_cfa_register %r1
+; CHECK-NEXT:agfi %r1, -69632
+; CHECK-NEXT:.cfi_def_cfa_offset 69792
+; CHECK-NEXT:  .LBB2_1: # =>This Inner Loop Header: Depth=1
+; CHECK-NEXT:aghi %r15, -4096
+; CHECK-NEXT:cg %r0, 4088(%r15)
+; CHECK-NEXT:clgrjh %r15, %r1, .LBB2_1
+; CHECK-NEXT:  # %bb.2:
+; CHECK-NEXT:.cfi_def_cfa_register %r15
+; CHECK-NEXT:aghi %r15, -2544
+; CHECK-NEXT:.cfi_def_cfa_offset 72336
+; CHECK-NEXT:cg %r0, 2536(%r15)
+; CHECK-NEXT:lhi %r0, 1
+; CHECK-NEXT:mvhi 568(%r15), 1
+; CHECK-NEXT:sty %r0, 28968(%r15)
+; CHECK-NEXT:l %r2, 176(%r15)
+; CHECK-NEXT:agfi %r15, 72176
+; CHECK-NEXT:br %r14
+
+  %a = alloca i32, i64 18000
+  %b0 = getelementptr inbounds i32, i32* %a, i64 98
+  %b1 = getelementptr inbounds i32, i32* %a, i64 7198
+  store volatile i32 1, i32* %b0
+  store volatile i32 1, i32* %b1
+  %c = load volatile i32, i32* %a
+  ret i32 %c
+}
+
+; Ends evenly on the step so no remainder needed.
+define void @fun3() #0 {
+; CHECK-LABEL: fun3:
+; CHECK:   # %bb.0: # %entry
+; CHECK-NEXT:lgr %r1, %r15
+; CHECK-NEXT:.cfi_def_cfa_register %r1
+; CHECK-NEXT:aghi %r1, -28672
+; CHECK-NEXT:.cfi_def_cfa_offset 28832
+; CHECK-NEXT:  .LBB3_1: # %entry
+; CHECK-NEXT:# =>This Inner Loop Header: Depth=1
+; CHECK-NEXT:aghi %r15, -4096
+; CHECK-NEXT:cg %r0, 4088(%r15)
+; CHECK-NEXT:clgrjh %r15, %r1, .LBB3_1
+; CHECK-NEXT:  # %bb.2: # %entry
+; CHECK-NEXT:.cfi_def_cfa_register %r15
+; CHECK-NEXT:mvhi 180(%r15), 0
+; CHECK-NEXT:l %r0, 180(%r15)
+; CHECK-NEXT:aghi %r15, 28672
+; CHECK-NEXT:br %r14
+entry:
+  %stack = alloca [7122 x i32], align 4
+  %i = alloca i32, align 4
+  %0 = bitcast [7122 x i32]* %stack to i8*
+  %i.0.i.0..sroa_cast = bitcast i32* %i to i8*
+  store volatile i32 0, i32* %i, align 4
+  %i.0.i.0.6 = load volatile i32, i32* %i, align 4
+  ret void
+}
+
+; Loop with bigger step.
+define void @fun4() #0 "stack-probe-size"="8192" {
+; CHECK-LABEL: fun4:
+; CHECK:   # %bb.0: # %entry
+; CHECK-NEXT:lgr 

[PATCH] D74506: [SystemZ] Support the kernel backchain

2020-02-23 Thread Jonas Paulsson via Phabricator via cfe-commits
This revision was automatically updated to reflect the committed changes.
Closed by commit rG82879c2913da: [SystemZ]  Support the kernel back chain. 
(authored by jonpa).
Herald added a project: clang.
Herald added a subscriber: cfe-commits.

Changed prior to commit:
  https://reviews.llvm.org/D74506?vs=246076=246126#toc

Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D74506

Files:
  clang/lib/Driver/ToolChains/Clang.cpp
  clang/test/Driver/mbackchain.c
  llvm/lib/Target/SystemZ/SystemZFrameLowering.cpp
  llvm/lib/Target/SystemZ/SystemZFrameLowering.h
  llvm/lib/Target/SystemZ/SystemZISelLowering.cpp
  llvm/test/CodeGen/SystemZ/frame-23.ll
  llvm/test/CodeGen/SystemZ/frame-24.ll
  llvm/test/CodeGen/SystemZ/frameaddr-02.ll

Index: llvm/test/CodeGen/SystemZ/frameaddr-02.ll
===
--- /dev/null
+++ llvm/test/CodeGen/SystemZ/frameaddr-02.ll
@@ -0,0 +1,54 @@
+; RUN: llc < %s -mtriple=s390x-linux-gnu | FileCheck %s
+
+; Test lowering of @llvm.frameaddress with packed-stack.
+
+; With back chain
+attributes #0 = { nounwind "packed-stack" "backchain" "use-soft-float"="true" }
+define i8* @fp0() #0 {
+entry:
+; CHECK-LABEL: fp0:
+; CHECK:  la   %r2, 152(%r15)
+; CHECK-NEXT: br   %r14
+  %0 = tail call i8* @llvm.frameaddress(i32 0)
+  ret i8* %0
+}
+
+define i8* @fp0f() #0 {
+entry:
+; CHECK-LABEL: fp0f:
+; CHECK:  lgr	%r1, %r15
+; CHECK-NEXT: aghi	%r15, -16
+; CHECK-NEXT: stg	%r1, 152(%r15)
+; CHECK-NEXT: la	%r2, 168(%r15)
+; CHECK-NEXT: aghi	%r15, 16
+; CHECK-NEXT: br	%r14
+  %0 = alloca i64, align 8
+  %1 = tail call i8* @llvm.frameaddress(i32 0)
+  ret i8* %1
+}
+
+; Without back chain
+
+attributes #1 = { nounwind "packed-stack" }
+define i8* @fp1() #1 {
+entry:
+; CHECK-LABEL: fp1:
+; CHECK:  lghi %r2, 0
+; CHECK-NEXT: br   %r14
+  %0 = tail call i8* @llvm.frameaddress(i32 0)
+  ret i8* %0
+}
+
+define i8* @fp1f() #1 {
+entry:
+; CHECK-LABEL: fp1f:
+; CHECK:  aghi	%r15, -8
+; CHECK-NEXT: lghi	%r2, 0
+; CHECK-NEXT: aghi	%r15, 8
+; CHECK-NEXT: br	%r14
+  %0 = alloca i64, align 8
+  %1 = tail call i8* @llvm.frameaddress(i32 0)
+  ret i8* %1
+}
+
+declare i8* @llvm.frameaddress(i32) nounwind readnone
Index: llvm/test/CodeGen/SystemZ/frame-24.ll
===
--- /dev/null
+++ llvm/test/CodeGen/SystemZ/frame-24.ll
@@ -0,0 +1,72 @@
+; RUN: llc < %s -mtriple=s390x-linux-gnu | FileCheck %s
+;
+; Test saving of vararg registers and backchain with packed stack.
+
+%struct.__va_list_tag = type { i64, i64, i8*, i8* }
+declare void @llvm.va_start(i8*)
+
+attributes #0 = { nounwind "packed-stack"="true" }
+define void @fun0(i64 %g0, double %d0, i64 %n, ...) #0 {
+; CHECK-LABEL: fun0:
+; CHECK:  stmg	%r4, %r15, 32(%r15)
+; CHECK-NEXT: aghi	%r15, -192
+; CHECK-NEXT: std	%f2, 328(%r15)
+; CHECK-NEXT: std	%f4, 336(%r15)
+; CHECK-NEXT: std	%f6, 344(%r15)
+; CHECK-NEXT: la	%r0, 352(%r15)
+; CHECK-NEXT: stg	%r0, 176(%r15)
+; CHECK-NEXT: la	%r0, 192(%r15)
+; CHECK-NEXT: stg	%r0, 184(%r15)
+; CHECK-NEXT: mvghi	160(%r15), 2
+; CHECK-NEXT: mvghi	168(%r15), 1
+; CHECK-NEXT: lmg	%r6, %r15, 240(%r15)
+; CHECK-NEXT: br	%r14
+entry:
+  %vl = alloca [1 x %struct.__va_list_tag], align 8
+  %0 = bitcast [1 x %struct.__va_list_tag]* %vl to i8*
+  call void @llvm.va_start(i8* nonnull %0)
+  ret void
+}
+
+attributes #1 = { nounwind "packed-stack"="true" "use-soft-float"="true" }
+define void @fun1(i64 %g0, double %d0, i64 %n, ...) #1 {
+; CHECK-LABEL: fun1:
+; CHECK:  stmg	%r5, %r15, 72(%r15)
+; CHECK-NEXT: aghi	%r15, -160
+; CHECK-NEXT: la	%r0, 192(%r15)
+; CHECK-NEXT: stg	%r0, 184(%r15)
+; CHECK-NEXT: la	%r0, 320(%r15)
+; CHECK-NEXT: stg	%r0, 176(%r15)
+; CHECK-NEXT: mvghi	168(%r15), 0
+; CHECK-NEXT: mvghi	160(%r15), 3
+; CHECK-NEXT: lmg	%r6, %r15, 240(%r15)
+; CHECK-NEXT: br	%r14
+entry:
+  %vl = alloca [1 x %struct.__va_list_tag], align 8
+  %0 = bitcast [1 x %struct.__va_list_tag]* %vl to i8*
+  call void @llvm.va_start(i8* nonnull %0)
+  ret void
+}
+
+attributes #2 = { nounwind "packed-stack"="true" "use-soft-float"="true" "backchain"}
+define void @fun2(i64 %g0, double %d0, i64 %n, ...) #2 {
+; CHECK-LABEL: fun2:
+; CHECK:  stmg	%r5, %r15, 64(%r15)
+; CHECK-NEXT: lgr	%r1, %r15
+; CHECK-NEXT: aghi	%r15, -168
+; CHECK-NEXT: stg	%r1, 152(%r15)
+; CHECK-NEXT: la	%r0, 192(%r15)
+; CHECK-NEXT: stg	%r0, 184(%r15)
+; CHECK-NEXT: la	%r0, 328(%r15)
+; CHECK-NEXT: stg	%r0, 176(%r15)
+; CHECK-NEXT: mvghi	168(%r15), 0
+; CHECK-NEXT: mvghi	160(%r15), 3
+; CHECK-NEXT: lmg	%r6, %r15, 240(%r15)
+; CHECK-NEXT: br	%r14
+entry:
+  %vl = alloca [1 x %struct.__va_list_tag], align 8
+  %0 = bitcast [1 x %struct.__va_list_tag]* %vl to i8*
+  call void @llvm.va_start(i8* nonnull %0)
+  ret void
+}
+
Index: llvm/test/CodeGen/SystemZ/frame-23.ll
===
--- /dev/null
+++ 

[PATCH] D72189: [SystemZ] Support -msoft-float

2020-02-04 Thread Jonas Paulsson via Phabricator via cfe-commits
jonpa added a comment.

In D72189#1857098 , @thakis wrote:

> Hello, this breaks tests on all platforms (e.g.: 
> http://45.33.8.238/mac/7170/step_11.txt) Please revert immediately and please 
> run tests locally before committing next time.


I have added the missing 'REQUIRES', and -mtriple:s to the tests which was not 
needed when I tested locally. Sorry for the noise.


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D72189



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


[PATCH] D72189: [SystemZ] Support -msoft-float

2020-02-04 Thread Jonas Paulsson via Phabricator via cfe-commits
This revision was automatically updated to reflect the committed changes.
Closed by commit rG563e84790f41: [SystemZ]  Support -msoft-float (authored by 
jonpa).
Herald added a project: clang.
Herald added a subscriber: cfe-commits.

Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D72189

Files:
  clang/lib/Basic/Targets/SystemZ.h
  clang/lib/CodeGen/TargetInfo.cpp
  clang/lib/Driver/ToolChains/Arch/SystemZ.cpp
  clang/lib/Driver/ToolChains/Arch/SystemZ.h
  clang/lib/Driver/ToolChains/Clang.cpp
  clang/test/CodeGen/systemz-abi.c
  clang/test/CodeGen/systemz-abi.cpp
  clang/test/CodeGen/target-data.c
  clang/test/Driver/systemz-float-01.c
  clang/test/Driver/systemz-float-02.c
  llvm/lib/Target/SystemZ/SystemZFeatures.td
  llvm/lib/Target/SystemZ/SystemZISelLowering.cpp
  llvm/lib/Target/SystemZ/SystemZISelLowering.h
  llvm/lib/Target/SystemZ/SystemZSubtarget.cpp
  llvm/lib/Target/SystemZ/SystemZSubtarget.h
  llvm/lib/Target/SystemZ/SystemZTargetMachine.cpp
  llvm/test/CodeGen/SystemZ/args-07.ll
  llvm/test/CodeGen/SystemZ/soft-float-01.ll
  llvm/test/CodeGen/SystemZ/soft-float-02.ll
  llvm/test/CodeGen/SystemZ/soft-float-03.ll
  llvm/test/CodeGen/SystemZ/soft-float-04.ll
  llvm/test/CodeGen/SystemZ/soft-float-args.ll
  llvm/test/CodeGen/SystemZ/soft-float-inline-asm-01.ll
  llvm/test/CodeGen/SystemZ/soft-float-inline-asm-02.ll
  llvm/test/CodeGen/SystemZ/soft-float-inline-asm-03.ll
  llvm/test/CodeGen/SystemZ/vec-abi-align.ll
  llvm/test/CodeGen/SystemZ/vec-args-06.ll
  llvm/test/CodeGen/SystemZ/vec-args-07.ll

Index: llvm/test/CodeGen/SystemZ/vec-args-07.ll
===
--- llvm/test/CodeGen/SystemZ/vec-args-07.ll
+++ llvm/test/CodeGen/SystemZ/vec-args-07.ll
@@ -1,6 +1,8 @@
 ; Test calling functions with multiple return values (LLVM ABI extension)
 ;
 ; RUN: llc < %s -mtriple=s390x-linux-gnu -mcpu=z13 | FileCheck %s
+; RUN: llc < %s -mtriple=s390x-linux-gnu -mcpu=z13 -mattr=soft-float \
+; RUN:   | FileCheck %s --check-prefix=SOFT-FLOAT
 
 ; Up to eight vector return values fit into VRs.
 declare { <2 x double>, <2 x double>, <2 x double>, <2 x double>,
@@ -11,6 +13,14 @@
 ; CHECK: brasl %r14, bar1
 ; CHECK: vlr %v24, %v31
 ; CHECK: br %r14
+
+; SOFT-FLOAT-LABEL: f1:
+; SOFT-FLOAT-NOT: %{{[fv]}}
+; SOFT-FLOAT: brasl   %r14, bar1
+; SOFT-FLOAT-NEXT: lg  %r3, 280(%r15)
+; SOFT-FLOAT-NEXT: lg  %r2, 272(%r15)
+; SOFT-FLOAT-NEXT: lmg %r14, %r15, 400(%r15)
+; SOFT-FLOAT-NEXT: br  %r14
   %mret = call { <2 x double>, <2 x double>,
  <2 x double>, <2 x double>,
  <2 x double>, <2 x double>,
@@ -33,6 +43,14 @@
 ; CHECK: brasl %r14, bar2
 ; CHECK: vl  %v24, 288(%r15)
 ; CHECK: br %r14
+
+; SOFT-FLOAT-LABEL: f2:
+; SOFT-FLOAT-NOT: %{{[fv]}}
+; SOFT-FLOAT: brasl   %r14, bar2
+; SOFT-FLOAT-NEXT: lg  %r3, 296(%r15)
+; SOFT-FLOAT-NEXT: lg  %r2, 288(%r15)
+; SOFT-FLOAT-NEXT: lmg %r14, %r15, 416(%r15)
+; SOFT-FLOAT-NEXT: br  %r14
   %mret = call { <2 x double>, <2 x double>,
  <2 x double>, <2 x double>,
  <2 x double>, <2 x double>,
Index: llvm/test/CodeGen/SystemZ/vec-args-06.ll
===
--- llvm/test/CodeGen/SystemZ/vec-args-06.ll
+++ llvm/test/CodeGen/SystemZ/vec-args-06.ll
@@ -1,6 +1,8 @@
 ; Test multiple return values (LLVM ABI extension)
 ;
 ; RUN: llc < %s -mtriple=s390x-linux-gnu -mcpu=z13 | FileCheck %s
+; RUN: llc < %s -mtriple=s390x-linux-gnu -mcpu=z13 -mattr=soft-float \
+; RUN:   | FileCheck %s --check-prefix=SOFT-FLOAT
 
 ; Up to eight vector return values fit into VRs.
 define { <2 x double>, <2 x double>, <2 x double>, <2 x double>,
@@ -23,6 +25,17 @@
 ; CHECK: larl [[TMP:%r[0-5]]], .LCPI
 ; CHECK: vl %v31, 0([[TMP]])
 ; CHECK: br %r14
+
+; SOFT-FLOAT-LABEL: f1:
+; SOFT-FLOAT-NOT: %{{[fv]}}
+; SOFT-FLOAT: llihf
+; SOFT-FLOAT-NEXT: oilf
+; SOFT-FLOAT-NEXT: stg
+; SOFT-FLOAT-NEXT: llihh
+; SOFT-FLOAT-NEXT: stg
+; SOFT-FLOAT-NEXT: llihf
+; SOFT-FLOAT-NOT: %{{[fv]}}
+; SOFT-FLOAT: br  %r14
   ret { <2 x double>, <2 x double>, <2 x double>, <2 x double>,
 <2 x double>, <2 x double>, <2 x double>, <2 x double> }
   { <2 x double> ,
@@ -68,6 +81,17 @@
 ; CHECK: vl [[VTMP:%v[0-9]+]], 0([[TMP]])
 ; CHECK: vst [[VTMP]], 0(%r2)
 ; CHECK: br %r14
+
+; SOFT-FLOAT-LABEL: f2:
+; SOFT-FLOAT-NOT: %{{[fv]}}
+; SOFT-FLOAT: llihf
+; SOFT-FLOAT-NEXT: oilf
+; SOFT-FLOAT-NEXT: stg
+; SOFT-FLOAT-NEXT: llihh
+; SOFT-FLOAT-NEXT: stg
+; SOFT-FLOAT-NEXT: llihf
+; SOFT-FLOAT-NOT: %{{[fv]}}
+; SOFT-FLOAT: br  %r14
   ret { <2 x double>, <2 x double>, <2 x double>, <2 x double>,
 <2 x double>, <2 x double>, <2 x double>, <2 x double>,
 <2 x double> }
Index: llvm/test/CodeGen/SystemZ/vec-abi-align.ll
===
--- llvm/test/CodeGen/SystemZ/vec-abi-align.ll

[PATCH] D71669: [Clang FE, SystemZ] Don't add "true" value for the "mnop-mcount" attribute.

2019-12-18 Thread Jonas Paulsson via Phabricator via cfe-commits
jonpa closed this revision.
jonpa added a comment.

ca52059 


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

https://reviews.llvm.org/D71669



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


[PATCH] D71669: [Clang FE, SystemZ] Don't add "true" value for the "mnop-mcount" attribute.

2019-12-18 Thread Jonas Paulsson via Phabricator via cfe-commits
jonpa created this revision.
jonpa added a reviewer: uweigand.
Herald added a subscriber: hiraditya.
Herald added a project: LLVM.

Let the "mnop-mcount" function attribute simply be present or non-present.

Update SystemZ backend as well to use hasFnAttribute() instead.


https://reviews.llvm.org/D71669

Files:
  clang/lib/CodeGen/CodeGenFunction.cpp
  clang/test/CodeGen/mnop-mcount.c
  llvm/lib/Target/SystemZ/SystemZAsmPrinter.cpp
  llvm/lib/Target/SystemZ/SystemZISelDAGToDAG.cpp
  llvm/test/CodeGen/SystemZ/mnop-mcount-01.ll
  llvm/test/CodeGen/SystemZ/mnop-mcount-02.ll


Index: llvm/test/CodeGen/SystemZ/mnop-mcount-02.ll
===
--- llvm/test/CodeGen/SystemZ/mnop-mcount-02.ll
+++ llvm/test/CodeGen/SystemZ/mnop-mcount-02.ll
@@ -7,5 +7,4 @@
   ret void
 }
 
-attributes #0 = { "instrument-function-entry-inlined"="mcount" 
"mnop-mcount"="true" }
-
+attributes #0 = { "instrument-function-entry-inlined"="mcount" "mnop-mcount" }
Index: llvm/test/CodeGen/SystemZ/mnop-mcount-01.ll
===
--- llvm/test/CodeGen/SystemZ/mnop-mcount-01.ll
+++ llvm/test/CodeGen/SystemZ/mnop-mcount-01.ll
@@ -22,5 +22,5 @@
 }
 
 attributes #0 = { "fentry-call"="true" }
-attributes #1 = { "fentry-call"="true" "mnop-mcount"="true" }
+attributes #1 = { "fentry-call"="true" "mnop-mcount" }
 
Index: llvm/lib/Target/SystemZ/SystemZISelDAGToDAG.cpp
===
--- llvm/lib/Target/SystemZ/SystemZISelDAGToDAG.cpp
+++ llvm/lib/Target/SystemZ/SystemZISelDAGToDAG.cpp
@@ -347,7 +347,7 @@
 
   bool runOnMachineFunction(MachineFunction ) override {
 const Function  = MF.getFunction();
-if (F.getFnAttribute("mnop-mcount").getValueAsString() == "true" &&
+if (F.hasFnAttribute("mnop-mcount") &&
 F.getFnAttribute("fentry-call").getValueAsString() != "true")
   report_fatal_error("mnop-mcount only supported with fentry-call");
 
Index: llvm/lib/Target/SystemZ/SystemZAsmPrinter.cpp
===
--- llvm/lib/Target/SystemZ/SystemZAsmPrinter.cpp
+++ llvm/lib/Target/SystemZ/SystemZAsmPrinter.cpp
@@ -553,8 +553,7 @@
 void SystemZAsmPrinter::LowerFENTRY_CALL(const MachineInstr ,
  SystemZMCInstLower ) {
   MCContext  = MF->getContext();
-  if (MF->getFunction().getFnAttribute("mnop-mcount")
-   .getValueAsString() == "true") {
+  if (MF->getFunction().hasFnAttribute("mnop-mcount")) {
 EmitNop(Ctx, *OutStreamer, 6, getSubtargetInfo());
 return;
   }
Index: clang/test/CodeGen/mnop-mcount.c
===
--- clang/test/CodeGen/mnop-mcount.c
+++ clang/test/CodeGen/mnop-mcount.c
@@ -17,9 +17,9 @@
   return foo();
 }
 
-//CHECK: attributes #0 = { {{.*}}"mnop-mcount"="true"{{.*}} }
+//CHECK: attributes #0 = { {{.*}}"mnop-mcount"{{.*}} }
 //CHECK: attributes #1 = { {{.*}} }
-//CHECK-NOT: attributes #1 = { {{.*}}"mnop-mcount"="true"{{.*}} }
+//CHECK-NOT: attributes #1 = { {{.*}}"mnop-mcount"{{.*}} }
 //NOMFENTRY: error: option '-mnop-mcount' cannot be specified without 
'-mfentry'
 //NOPG-NOT: attributes #0 = { {{.*}}"mnop-mcount"{{.*}} }
 //NOPG-NOT: attributes #1 = { {{.*}}"mnop-mcount"{{.*}} }
Index: clang/lib/CodeGen/CodeGenFunction.cpp
===
--- clang/lib/CodeGen/CodeGenFunction.cpp
+++ clang/lib/CodeGen/CodeGenFunction.cpp
@@ -966,7 +966,7 @@
 if (!CGM.getCodeGenOpts().CallFEntry)
   CGM.getDiags().Report(diag::err_opt_not_valid_without_opt)
 << "-mnop-mcount" << "-mfentry";
-Fn->addFnAttr("mnop-mcount", "true");
+Fn->addFnAttr("mnop-mcount");
   }
 }
   }


Index: llvm/test/CodeGen/SystemZ/mnop-mcount-02.ll
===
--- llvm/test/CodeGen/SystemZ/mnop-mcount-02.ll
+++ llvm/test/CodeGen/SystemZ/mnop-mcount-02.ll
@@ -7,5 +7,4 @@
   ret void
 }
 
-attributes #0 = { "instrument-function-entry-inlined"="mcount" "mnop-mcount"="true" }
-
+attributes #0 = { "instrument-function-entry-inlined"="mcount" "mnop-mcount" }
Index: llvm/test/CodeGen/SystemZ/mnop-mcount-01.ll
===
--- llvm/test/CodeGen/SystemZ/mnop-mcount-01.ll
+++ llvm/test/CodeGen/SystemZ/mnop-mcount-01.ll
@@ -22,5 +22,5 @@
 }
 
 attributes #0 = { "fentry-call"="true" }
-attributes #1 = { "fentry-call"="true" "mnop-mcount"="true" }
+attributes #1 = { "fentry-call"="true" "mnop-mcount" }
 
Index: llvm/lib/Target/SystemZ/SystemZISelDAGToDAG.cpp
===
--- llvm/lib/Target/SystemZ/SystemZISelDAGToDAG.cpp
+++ llvm/lib/Target/SystemZ/SystemZISelDAGToDAG.cpp
@@ -347,7 +347,7 @@
 
   bool runOnMachineFunction(MachineFunction ) override {
 const Function 

[PATCH] D67763: [Clang FE] Recognize -mnop-mcount CL option

2019-11-05 Thread Jonas Paulsson via Phabricator via cfe-commits
jonpa closed this revision.
jonpa added a comment.

committed as 9376714 



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

https://reviews.llvm.org/D67763



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


[PATCH] D67763: [Clang FE] Recognize -mnop-mcount CL option

2019-10-22 Thread Jonas Paulsson via Phabricator via cfe-commits
jonpa added a comment.

ping!


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

https://reviews.llvm.org/D67763



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


[PATCH] D67763: [Clang FE] Recognize -mnop-mcount CL option

2019-10-15 Thread Jonas Paulsson via Phabricator via cfe-commits
jonpa added a reviewer: bkramer.
jonpa added a comment.

@Benjamin: I see that you removed the option that I am now putting back, so 
perhaps you could take a look and see if this patch looks ok? Thanks. /Jonas


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

https://reviews.llvm.org/D67763



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


[PATCH] D67763: [Clang FE] Recognize -mnop-mcount CL option

2019-10-08 Thread Jonas Paulsson via Phabricator via cfe-commits
jonpa added a comment.

ping!


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

https://reviews.llvm.org/D67763



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