Hi echristo, wschmidt, hfinkel, kbarton,

This patch provides some of the missing instructions from ISA 2.06. Namely the 
integer divide extended instructions (and associated builtins) are provided. 
The record-form variants are provided but can be accessed through inline 
assembly only.
Since these instructions are introduced with ISA 2.06, it is important that 
they not be emitted for targets that implement an older ISA. Also, since they 
are exposed in the front end through builtinins, it is important that the front 
end knows not to emit the intrinsics to the back end if the target does not 
support them. Therefore, this patch provides the ability to test whether the 
target is Power 7 and up (and Power 8 and up) and use of the builtins is 
diagnosed on older CPUs.
This diverges from GCC behaviour of controlling the builtins and instructions 
with -mpopcntd since that option has very little to do with these 
instructions/builtins.

Note: in a general case, a newer ISA is a superset of the previous ISA. 
However, instructions are sometimes removed from the ISA. This raises the 
question whether emitting instructions/builtins based on "IsPwr7Up", et. al. is 
the right approach. In my opinion, it is unlikely that something that is added 
in say ISA 2.06 will be removed any time soon, but I welcome other opinions.

REPOSITORY
  rL LLVM

http://reviews.llvm.org/D8398

Files:
  include/clang/Basic/BuiltinsPPC.def
  lib/Basic/Targets.cpp
  lib/CodeGen/CGBuiltin.cpp
  test/CodeGen/builtins-ppc-p7-disabled.c
  test/CodeGen/builtins-ppc-p7.c

EMAIL PREFERENCES
  http://reviews.llvm.org/settings/panel/emailpreferences/
Index: include/clang/Basic/BuiltinsPPC.def
===================================================================
--- include/clang/Basic/BuiltinsPPC.def
+++ include/clang/Basic/BuiltinsPPC.def
@@ -237,6 +237,13 @@
 BUILTIN(__builtin_vsx_xvdivdp, "V2dV2dV2d", "")
 BUILTIN(__builtin_vsx_xvdivsp, "V4fV4fV4f", "")
 
+// Scalar built-ins
+BUILTIN(__builtin_divwe, "SiSiSi", "")
+BUILTIN(__builtin_divweu, "UiUiUi", "")
+BUILTIN(__builtin_divde, "SLLiSLLiSLLi", "")
+BUILTIN(__builtin_divdeu, "ULLiULLiULLi", "")
+BUILTIN(__builtin_bpermd, "SLLiSLLiSLLi", "")
+
 // FIXME: Obviously incomplete.
 
 #undef BUILTIN
Index: lib/Basic/Targets.cpp
===================================================================
--- lib/Basic/Targets.cpp
+++ lib/Basic/Targets.cpp
@@ -720,6 +720,9 @@
   bool HasVSX;
   bool HasP8Vector;
   bool HasP8Crypto;
+  bool IsPwr7Up;
+  bool IsPwr8Up;
+  bool Is64Bit;
 
 protected:
   std::string ABI;
@@ -993,6 +996,12 @@
       continue;
     }
 
+    // We do not want to emit builtins that cannot be supported by the CPU
+    IsPwr8Up = CPU == "pwr8" || CPU == "ppc64le" ||
+                      getTriple().getArch() == llvm::Triple::ppc64le;
+    IsPwr7Up = CPU == "pwr7" || IsPwr8Up;
+    Is64Bit = PointerWidth == 64;
+
     // TODO: Finish this list and add an assert that we've handled them
     // all.
   }
@@ -1201,6 +1210,11 @@
     .Case("vsx", HasVSX)
     .Case("power8-vector", HasP8Vector)
     .Case("crypto", HasP8Crypto)
+    .Case("IsPwr7Up", IsPwr7Up)
+    .Case("IsISA206Up", IsPwr7Up)
+    .Case("IsPwr8Up", IsPwr8Up)
+    .Case("IsISA207Up", IsPwr8Up)
+    .Case("Is64Bit", Is64Bit)
     .Default(false);
 }
 
Index: lib/CodeGen/CGBuiltin.cpp
===================================================================
--- lib/CodeGen/CGBuiltin.cpp
+++ lib/CodeGen/CGBuiltin.cpp
@@ -6378,6 +6378,46 @@
     llvm::Function *F = CGM.getIntrinsic(ID);
     return Builder.CreateCall(F, Ops, "");
   }
+  case PPC::BI__builtin_divwe:
+  case PPC::BI__builtin_divweu:
+  case PPC::BI__builtin_divde:
+  case PPC::BI__builtin_divdeu:
+  case PPC::BI__builtin_bpermd:
+  {
+    bool Is64BitBltin = BuiltinID == PPC::BI__builtin_divde ||
+                        BuiltinID == PPC::BI__builtin_divdeu ||
+                        BuiltinID == PPC::BI__builtin_bpermd;
+    if(!getTarget().hasFeature("IsPwr7Up")) {
+      CGM.Error(E->getExprLoc(),
+                "This builtin is only valid on POWER7 or later CPUs");
+      return llvm::UndefValue::get(Ops[0]->getType());
+    }
+    if(!getTarget().hasFeature("Is64Bit") && Is64BitBltin) {
+      CGM.Error(E->getExprLoc(),
+                "This builtin is only available on 64-bit targets");
+      return llvm::UndefValue::get(Ops[0]->getType());
+    }
+    switch(BuiltinID) {
+    default: llvm_unreachable("Unsupported division intrinsic");
+    case PPC::BI__builtin_divwe:
+      ID = Intrinsic::ppc_divwe;
+      break;
+    case PPC::BI__builtin_divweu:
+      ID = Intrinsic::ppc_divweu;
+      break;
+    case PPC::BI__builtin_divde:
+      ID = Intrinsic::ppc_divde;
+      break;
+    case PPC::BI__builtin_divdeu:
+      ID = Intrinsic::ppc_divdeu;
+      break;
+    case PPC::BI__builtin_bpermd:
+      ID = Intrinsic::ppc_bpermd;
+      break;
+    }
+    llvm::Function *F = CGM.getIntrinsic(ID);
+    return Builder.CreateCall(F, Ops, "");
+  }
   }
 }
 
Index: test/CodeGen/builtins-ppc-p7-disabled.c
===================================================================
--- test/CodeGen/builtins-ppc-p7-disabled.c
+++ test/CodeGen/builtins-ppc-p7-disabled.c
@@ -0,0 +1,33 @@
+// REQUIRES: powerpc-registered-target
+// RUN: not %clang_cc1 -triple powerpc64-unknown-unknown \
+// RUN: -target-cpu pwr6 -emit-llvm %s -o - 2>&1 \
+// RUN: | FileCheck %s
+
+// RUN: not %clang_cc1 -triple powerpc-unknown-unknown -emit-llvm %s -o - 2>&1 \
+// RUN: -target-cpu pwr7 | FileCheck %s -check-prefix=CHECK-32
+
+void call_p7_builtins(void)
+{
+  int a = __builtin_divwe(33, 11);
+  unsigned int b = __builtin_divweu(33U, 11U);
+  unsigned long long d = __builtin_divde(33ULL, 11ULL);
+  unsigned long long e = __builtin_divdeu(33ULL, 11ULL);
+  unsigned long long f = __builtin_bpermd(33ULL, 11ULL);
+}
+
+// CHECK: error: This builtin is only valid on POWER7 or later CPUs
+// CHECK: __builtin_divwe
+// CHECK: error: This builtin is only valid on POWER7 or later CPUs
+// CHECK: __builtin_divweu
+// CHECK: error: This builtin is only valid on POWER7 or later CPUs
+// CHECK: __builtin_divde
+// CHECK: error: This builtin is only valid on POWER7 or later CPUs
+// CHECK: __builtin_divdeu
+// CHECK: error: This builtin is only valid on POWER7 or later CPUs
+// CHECK: __builtin_bpermd
+// CHECK-32: error: This builtin is only available on 64-bit targets
+// CHECK-32: __builtin_divde
+// CHECK-32: error: This builtin is only available on 64-bit targets
+// CHECK-32: __builtin_divdeu
+// CHECK-32: error: This builtin is only available on 64-bit targets
+// CHECK-32: __builtin_bpermd
Index: test/CodeGen/builtins-ppc-p7.c
===================================================================
--- test/CodeGen/builtins-ppc-p7.c
+++ test/CodeGen/builtins-ppc-p7.c
@@ -0,0 +1,52 @@
+// REQUIRES: powerpc-registered-target
+// RUN: %clang_cc1 -triple powerpc64-unknown-unknown -target-cpu pwr7 \
+// RUN: -emit-llvm %s -o - | FileCheck %s
+
+// RUN: %clang_cc1 -triple powerpc64le-unknown-unknown -target-cpu pwr8 \
+// RUN: -emit-llvm %s -o - | FileCheck %s
+
+// CHECK-LABEL: define signext i32 @test_divwe
+int test_divwe(void)
+{
+  int a = 74;
+  int b = 32;
+  return __builtin_divwe(a, b);
+// CHECK @llvm.ppc.divwe
+}
+
+// CHECK-LABEL: define zeroext i32 @test_divweu
+unsigned int test_divweu(void)
+{
+  unsigned int a = 74;
+  unsigned int b = 32;
+  return __builtin_divweu(a, b);
+// CHECK @llvm.ppc.divweu
+}
+
+// CHECK-LABEL: define i64 @test_divde
+long long test_divde(void)
+{
+  long long a = 74LL;
+  long long b = 32LL;
+  return __builtin_divde(a, b);
+// CHECK @llvm.ppc.divde
+}
+
+// CHECK-LABEL: define i64 @test_divdeu
+unsigned long long test_divdeu(void)
+{
+  unsigned long long a = 74ULL;
+  unsigned long long b = 32ULL;
+  return __builtin_divdeu(a, b);
+// CHECK @llvm.ppc.divdeu
+}
+
+// CHECK-LABEL: define i64 @test_bpermd
+long long test_bpermd(void)
+{
+  long long a = 74LL;
+  long long b = 32LL;
+  return __builtin_bpermd(a, b);
+// CHECK @llvm.ppc.bpermd
+}
+
_______________________________________________
cfe-commits mailing list
[email protected]
http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits

Reply via email to