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 i64 %1, i64* @Addr
+  ret i64 %1
+}
+
+define i64 @fun_BD20_T() {
+; CHECK-LABEL: fun_BD20_T:
+; 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,^ZT"(i64* nonnull %arrayidx)
+  store i64 %1, i64* @Addr
+  ret i64 %1
+}
+
 define i64 @fun_BD20_p() {
 ; CHECK-LABEL: fun_BD20_p:
 ; CHECK: #APP
@@ -42,6 +194,62 @@
   ret i64 %1
 }
 
+define i64 @fun_BDX20_Q() {
+; CHECK-LABEL: fun_BDX20_Q:
+; CHECK: #APP
+; CHECK: lay	%r2, 0(%r1)
+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,^ZQ"(i64* %arrayidx)
+  store i64 %2, i64* @Addr
+  ret i64 %2
+}
+
+define i64 @fun_BDX20_R() {
+; CHECK-LABEL: fun_BDX20_R:
+; CHECK: #APP
+; CHECK: lay	%r2, 0(%r1)
+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,^ZR"(i64* %arrayidx)
+  store i64 %2, i64* @Addr
+  ret i64 %2
+}
+
+define i64 @fun_BDX20_S() {
+; CHECK-LABEL: fun_BDX20_S:
+; CHECK: #APP
+; CHECK: lay	%r2, 8000(%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,^ZS"(i64* %arrayidx)
+  store i64 %2, i64* @Addr
+  ret i64 %2
+}
+
+define i64 @fun_BDX20_T() {
+; CHECK-LABEL: fun_BDX20_T:
+; 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,^ZT"(i64* %arrayidx)
+  store i64 %2, i64* @Addr
+  ret i64 %2
+}
+
 define i64 @fun_BDX20_p() {
 ; CHECK-LABEL: fun_BDX20_p:
 ; CHECK: #APP
Index: llvm/lib/Target/SystemZ/SystemZISelLowering.h
===================================================================
--- llvm/lib/Target/SystemZ/SystemZISelLowering.h
+++ llvm/lib/Target/SystemZ/SystemZISelLowering.h
@@ -497,6 +497,19 @@
       case 'T':
         return InlineAsm::Constraint_T;
       }
+    } else if (ConstraintCode.size() == 2 && ConstraintCode[0] == 'Z') {
+      switch (ConstraintCode[1]) {
+      default:
+        break;
+      case 'Q':
+        return InlineAsm::Constraint_ZQ;
+      case 'R':
+        return InlineAsm::Constraint_ZR;
+      case 'S':
+        return InlineAsm::Constraint_ZS;
+      case 'T':
+        return InlineAsm::Constraint_ZT;
+      }
     }
     return TargetLowering::getInlineAsmMemConstraint(ConstraintCode);
   }
Index: llvm/lib/Target/SystemZ/SystemZISelLowering.cpp
===================================================================
--- llvm/lib/Target/SystemZ/SystemZISelLowering.cpp
+++ llvm/lib/Target/SystemZ/SystemZISelLowering.cpp
@@ -1034,6 +1034,17 @@
     case 'M': // 0x7fffffff
       return C_Immediate;
 
+    default:
+      break;
+    }
+  } else if (Constraint.size() == 2 && Constraint[0] == 'Z') {
+    switch (Constraint[1]) {
+    case 'Q': // Address with base and unsigned 12-bit displacement
+    case 'R': // Likewise, plus an index
+    case 'S': // Address with base and signed 20-bit displacement
+    case 'T': // Likewise, plus an index
+      return C_Address;
+
     default:
       break;
     }
Index: llvm/lib/Target/SystemZ/SystemZISelDAGToDAG.cpp
===================================================================
--- llvm/lib/Target/SystemZ/SystemZISelDAGToDAG.cpp
+++ llvm/lib/Target/SystemZ/SystemZISelDAGToDAG.cpp
@@ -1683,16 +1683,19 @@
     llvm_unreachable("Unexpected asm memory constraint");
   case InlineAsm::Constraint_i:
   case InlineAsm::Constraint_Q:
+  case InlineAsm::Constraint_ZQ:
     // Accept an address with a short displacement, but no index.
     Form = SystemZAddressingMode::FormBD;
     DispRange = SystemZAddressingMode::Disp12Only;
     break;
   case InlineAsm::Constraint_R:
+  case InlineAsm::Constraint_ZR:
     // Accept an address with a short displacement and an index.
     Form = SystemZAddressingMode::FormBDXNormal;
     DispRange = SystemZAddressingMode::Disp12Only;
     break;
   case InlineAsm::Constraint_S:
+  case InlineAsm::Constraint_ZS:
     // Accept an address with a long displacement, but no index.
     Form = SystemZAddressingMode::FormBD;
     DispRange = SystemZAddressingMode::Disp20Only;
@@ -1701,6 +1704,7 @@
   case InlineAsm::Constraint_m:
   case InlineAsm::Constraint_o:
   case InlineAsm::Constraint_p:
+  case InlineAsm::Constraint_ZT:
     // 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/include/llvm/IR/InlineAsm.h
===================================================================
--- llvm/include/llvm/IR/InlineAsm.h
+++ llvm/include/llvm/IR/InlineAsm.h
@@ -274,8 +274,12 @@
 
     // Address constraints
     Constraint_p,
+    Constraint_ZQ,
+    Constraint_ZR,
+    Constraint_ZS,
+    Constraint_ZT,
 
-    Constraints_Max = Constraint_p,
+    Constraints_Max = Constraint_ZT,
     Constraints_ShiftAmount = 16,
 
     Flag_MatchingOperand = 0x80000000
@@ -462,6 +466,14 @@
       return "Zy";
     case InlineAsm::Constraint_p:
       return "p";
+    case InlineAsm::Constraint_ZQ:
+      return "ZQ";
+    case InlineAsm::Constraint_ZR:
+      return "ZR";
+    case InlineAsm::Constraint_ZS:
+      return "ZS";
+    case InlineAsm::Constraint_ZT:
+      return "ZT";
     default:
       llvm_unreachable("Unknown memory constraint");
     }
Index: clang/test/CodeGen/SystemZ/systemz-inline-asm-03.c
===================================================================
--- clang/test/CodeGen/SystemZ/systemz-inline-asm-03.c
+++ clang/test/CodeGen/SystemZ/systemz-inline-asm-03.c
@@ -6,6 +6,34 @@
 long Idx;
 unsigned long Addr;
 
+unsigned long fun_BD12_Q() {
+// CHECK-LABEL: define{{.*}} i64 @fun_BD12_Q()
+// CHECK: call i64 asm "lay $0, $1", "=r,^ZQ"(i64* nonnull %arrayidx)
+  asm("lay %0, %1" : "=r" (Addr) : "ZQ" (&A[100]));
+  return Addr;
+}
+
+unsigned long fun_BD12_R() {
+// CHECK-LABEL: define{{.*}} i64 @fun_BD12_R()
+// CHECK: call i64 asm "lay $0, $1", "=r,^ZR"(i64* nonnull %arrayidx)
+  asm("lay %0, %1" : "=r" (Addr) : "ZR" (&A[100]));
+  return Addr;
+}
+
+unsigned long fun_BD12_S() {
+// CHECK-LABEL: define{{.*}} i64 @fun_BD12_S()
+// CHECK: call i64 asm "lay $0, $1", "=r,^ZS"(i64* nonnull %arrayidx)
+  asm("lay %0, %1" : "=r" (Addr) : "ZS" (&A[100]));
+  return Addr;
+}
+
+unsigned long fun_BD12_T() {
+// CHECK-LABEL: define{{.*}} i64 @fun_BD12_T()
+// CHECK: call i64 asm "lay $0, $1", "=r,^ZT"(i64* nonnull %arrayidx)
+  asm("lay %0, %1" : "=r" (Addr) : "ZT" (&A[100]));
+  return Addr;
+}
+
 unsigned long fun_BD12_p() {
 // CHECK-LABEL: define{{.*}} i64 @fun_BD12_p()
 // CHECK: call i64 asm "lay $0, $1", "=r,p"(i64* nonnull %arrayidx)
@@ -13,6 +41,34 @@
   return Addr;
 }
 
+unsigned long fun_BDX12_Q() {
+// CHECK-LABEL: define{{.*}} i64 @fun_BDX12_Q()
+// CHECK: call i64 asm "lay $0, $1", "=r,^ZQ"(i64* %arrayidx)
+  asm("lay %0, %1" : "=r" (Addr) : "ZQ" (&A[Idx + 100]));
+  return Addr;
+}
+
+unsigned long fun_BDX12_R() {
+// CHECK-LABEL: define{{.*}} i64 @fun_BDX12_R()
+// CHECK: call i64 asm "lay $0, $1", "=r,^ZR"(i64* %arrayidx)
+  asm("lay %0, %1" : "=r" (Addr) : "ZR" (&A[Idx + 100]));
+  return Addr;
+}
+
+unsigned long fun_BDX12_S() {
+// CHECK-LABEL: define{{.*}} i64 @fun_BDX12_S()
+// CHECK: call i64 asm "lay $0, $1", "=r,^ZS"(i64* %arrayidx)
+  asm("lay %0, %1" : "=r" (Addr) : "ZS" (&A[Idx + 100]));
+  return Addr;
+}
+
+unsigned long fun_BDX12_T() {
+// CHECK-LABEL: define{{.*}} i64 @fun_BDX12_T()
+// CHECK: call i64 asm "lay $0, $1", "=r,^ZT"(i64* %arrayidx)
+  asm("lay %0, %1" : "=r" (Addr) : "ZT" (&A[Idx + 100]));
+  return Addr;
+}
+
 unsigned long fun_BDX12_p() {
 // CHECK-LABEL: define{{.*}} i64 @fun_BDX12_p()
 // CHECK: call i64 asm "lay $0, $1", "=r,p"(i64* %arrayidx)
@@ -20,6 +76,34 @@
   return Addr;
 }
 
+unsigned long fun_BD20_Q() {
+// CHECK-LABEL: define{{.*}} i64 @fun_BD20_Q()
+// CHECK: call i64 asm "lay $0, $1", "=r,^ZQ"(i64* nonnull %arrayidx)
+  asm("lay %0, %1" : "=r" (Addr) : "ZQ" (&A[1000]));
+  return Addr;
+}
+
+unsigned long fun_BD20_R() {
+// CHECK-LABEL: define{{.*}} i64 @fun_BD20_R()
+// CHECK: call i64 asm "lay $0, $1", "=r,^ZR"(i64* nonnull %arrayidx)
+  asm("lay %0, %1" : "=r" (Addr) : "ZR" (&A[1000]));
+  return Addr;
+}
+
+unsigned long fun_BD20_S() {
+// CHECK-LABEL: define{{.*}} i64 @fun_BD20_S()
+// CHECK: call i64 asm "lay $0, $1", "=r,^ZS"(i64* nonnull %arrayidx)
+  asm("lay %0, %1" : "=r" (Addr) : "ZS" (&A[1000]));
+  return Addr;
+}
+
+unsigned long fun_BD20_T() {
+// CHECK-LABEL: define{{.*}} i64 @fun_BD20_T()
+// CHECK: call i64 asm "lay $0, $1", "=r,^ZT"(i64* nonnull %arrayidx)
+  asm("lay %0, %1" : "=r" (Addr) : "ZT" (&A[1000]));
+  return Addr;
+}
+
 unsigned long fun_BD20_p() {
 // CHECK-LABEL: define{{.*}} i64 @fun_BD20_p()
 // CHECK: call i64 asm "lay $0, $1", "=r,p"(i64* nonnull %arrayidx)
@@ -27,6 +111,34 @@
   return Addr;
 }
 
+unsigned long fun_BDX20_Q() {
+// CHECK-LABEL: define{{.*}} i64 @fun_BDX20_Q()
+// CHECK: call i64 asm "lay $0, $1", "=r,^ZQ"(i64* %arrayidx)
+  asm("lay %0, %1" : "=r" (Addr) : "ZQ" (&A[Idx + 1000]));
+  return Addr;
+}
+
+unsigned long fun_BDX20_R() {
+// CHECK-LABEL: define{{.*}} i64 @fun_BDX20_R()
+// CHECK: call i64 asm "lay $0, $1", "=r,^ZR"(i64* %arrayidx)
+  asm("lay %0, %1" : "=r" (Addr) : "ZR" (&A[Idx + 1000]));
+  return Addr;
+}
+
+unsigned long fun_BDX20_S() {
+// CHECK-LABEL: define{{.*}} i64 @fun_BDX20_S()
+// CHECK: call i64 asm "lay $0, $1", "=r,^ZS"(i64* %arrayidx)
+  asm("lay %0, %1" : "=r" (Addr) : "ZS" (&A[Idx + 1000]));
+  return Addr;
+}
+
+unsigned long fun_BDX20_T() {
+// CHECK-LABEL: define{{.*}} i64 @fun_BDX20_T()
+// CHECK: call i64 asm "lay $0, $1", "=r,^ZT"(i64* %arrayidx)
+  asm("lay %0, %1" : "=r" (Addr) : "ZT" (&A[Idx + 1000]));
+  return Addr;
+}
+
 unsigned long fun_BDX20_p() {
 // CHECK-LABEL: define{{.*}} i64 @fun_BDX20_p()
 // CHECK: call i64 asm "lay $0, $1", "=r,p"(i64* %arrayidx)
Index: clang/lib/Basic/Targets/SystemZ.h
===================================================================
--- clang/lib/Basic/Targets/SystemZ.h
+++ clang/lib/Basic/Targets/SystemZ.h
@@ -86,6 +86,20 @@
     switch (Constraint[0]) {
     case 'p': // Keep 'p' constraint.
       return std::string("p");
+    case 'Z':
+      switch (Constraint[1]) {
+      case 'Q': // Address with base and unsigned 12-bit displacement
+      case 'R': // Likewise, plus an index
+      case 'S': // Address with base and signed 20-bit displacement
+      case 'T': // Likewise, plus an index
+        // "^" hints llvm that this is a 2 letter constraint.
+        // "Constraint++" is used to promote the string iterator
+        // to the next constraint.
+        return std::string("^") + std::string(Constraint++, 2);
+      default:
+        break;
+      }
+      break;
     default:
       break;
     }
Index: clang/lib/Basic/Targets/SystemZ.cpp
===================================================================
--- clang/lib/Basic/Targets/SystemZ.cpp
+++ clang/lib/Basic/Targets/SystemZ.cpp
@@ -59,6 +59,17 @@
   default:
     return false;
 
+  case 'Z':
+    switch (Name[1]) {
+    default:
+      return false;
+    case 'Q': // Address with base and unsigned 12-bit displacement
+    case 'R': // Likewise, plus an index
+    case 'S': // Address with base and signed 20-bit displacement
+    case 'T': // Likewise, plus an index
+      break;
+    }
+    LLVM_FALLTHROUGH;
   case 'a': // Address register
   case 'd': // Data register (equivalent to 'r')
   case 'f': // Floating-point register
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to