[PATCH] D70256: [FPEnv] clang support for constrained FP builtins

2019-12-10 Thread Kevin P. Neal via Phabricator via cfe-commits
This revision was automatically updated to reflect the committed changes.
Closed by commit rG6515c524b0ae: [FPEnv] clang support for constrained FP 
builtins (authored by kpn).

Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D70256

Files:
  clang/lib/CodeGen/CGBuiltin.cpp
  clang/test/CodeGen/constrained-math-builtins.c
  llvm/include/llvm/IR/IRBuilder.h

Index: llvm/include/llvm/IR/IRBuilder.h
===
--- llvm/include/llvm/IR/IRBuilder.h
+++ llvm/include/llvm/IR/IRBuilder.h
@@ -2087,6 +2087,8 @@
 case Intrinsic::experimental_constrained_fpext:
 case Intrinsic::experimental_constrained_fptoui:
 case Intrinsic::experimental_constrained_fptosi:
+case Intrinsic::experimental_constrained_lround:
+case Intrinsic::experimental_constrained_llround:
   C = CreateIntrinsic(ID, {DestTy, V->getType()}, {V, ExceptV}, nullptr,
   Name);
   break;
@@ -2297,6 +2299,37 @@
 Args, OpBundles, Name, FPMathTag);
   }
 
+  // Deprecated [opaque pointer types]
+  CallInst *CreateConstrainedFPCall(
+  Value *Callee, ArrayRef Args, const Twine  = "",
+  Optional Rounding = None,
+  Optional Except = None) {
+llvm::SmallVector UseArgs;
+
+for (auto *OneArg : Args)
+  UseArgs.push_back(OneArg);
+Function *F = cast(Callee);
+switch (F->getIntrinsicID()) {
+default:
+  UseArgs.push_back(getConstrainedFPRounding(Rounding));
+  break;
+case Intrinsic::experimental_constrained_fpext:
+case Intrinsic::experimental_constrained_fptoui:
+case Intrinsic::experimental_constrained_fptosi:
+case Intrinsic::experimental_constrained_lround:
+case Intrinsic::experimental_constrained_llround:
+  // No rounding metadata for these intrinsics.
+  break;
+}
+UseArgs.push_back(getConstrainedFPExcept(Except));
+
+CallInst *C = CreateCall(
+cast(Callee->getType()->getPointerElementType()), Callee,
+UseArgs, Name);
+setConstrainedFPCallAttr(C);
+return C;
+  }
+
   Value *CreateSelect(Value *C, Value *True, Value *False,
   const Twine  = "", Instruction *MDFrom = nullptr) {
 if (auto *CC = dyn_cast(C))
Index: clang/test/CodeGen/constrained-math-builtins.c
===
--- /dev/null
+++ clang/test/CodeGen/constrained-math-builtins.c
@@ -0,0 +1,150 @@
+// RUN: %clang_cc1 -triple x86_64-linux -ffp-exception-behavior=strict -w -S -o - -emit-llvm %s | FileCheck %s
+
+// Test codegen of constrained math builtins.
+
+void foo(double *d, float f, float *fp, long double *l, int *i, const char *c) {
+  f = __builtin_fmod(f,f);f = __builtin_fmodf(f,f);   f =  __builtin_fmodl(f,f);
+
+// CHECK: declare double @llvm.experimental.constrained.frem.f64(double, double, metadata, metadata)
+// CHECK: declare float @llvm.experimental.constrained.frem.f32(float, float, metadata, metadata)
+// CHECK: declare x86_fp80 @llvm.experimental.constrained.frem.f80(x86_fp80, x86_fp80, metadata, metadata)
+
+  __builtin_pow(f,f);__builtin_powf(f,f);   __builtin_powl(f,f);
+
+// CHECK: declare double @llvm.experimental.constrained.pow.f64(double, double, metadata, metadata)
+// CHECK: declare float @llvm.experimental.constrained.pow.f32(float, float, metadata, metadata)
+// CHECK: declare x86_fp80 @llvm.experimental.constrained.pow.f80(x86_fp80, x86_fp80, metadata, metadata)
+
+  __builtin_powi(f,f);__builtin_powif(f,f);   __builtin_powil(f,f);
+
+// CHECK: declare double @llvm.experimental.constrained.powi.f64(double, i32, metadata, metadata)
+// CHECK: declare float @llvm.experimental.constrained.powi.f32(float, i32, metadata, metadata)
+// CHECK: declare x86_fp80 @llvm.experimental.constrained.powi.f80(x86_fp80, i32, metadata, metadata)
+
+  __builtin_ceil(f);   __builtin_ceilf(f);  __builtin_ceill(f);
+
+// CHECK: declare double @llvm.experimental.constrained.ceil.f64(double, metadata, metadata)
+// CHECK: declare float @llvm.experimental.constrained.ceil.f32(float, metadata, metadata)
+// CHECK: declare x86_fp80 @llvm.experimental.constrained.ceil.f80(x86_fp80, metadata, metadata)
+
+  __builtin_cos(f);__builtin_cosf(f);   __builtin_cosl(f); 
+
+// CHECK: declare double @llvm.experimental.constrained.cos.f64(double, metadata, metadata)
+// CHECK: declare float @llvm.experimental.constrained.cos.f32(float, metadata, metadata)
+// CHECK: declare x86_fp80 @llvm.experimental.constrained.cos.f80(x86_fp80, metadata, metadata)
+
+  __builtin_exp(f);__builtin_expf(f);   __builtin_expl(f);
+
+// CHECK: declare double @llvm.experimental.constrained.exp.f64(double, metadata, metadata)
+// CHECK: declare float @llvm.experimental.constrained.exp.f32(float, metadata, metadata)
+// CHECK: declare x86_fp80 @llvm.experimental.constrained.exp.f80(x86_fp80, 

[PATCH] D70256: [FPEnv] clang support for constrained FP builtins

2019-12-10 Thread John McCall via Phabricator via cfe-commits
rjmccall accepted this revision.
rjmccall added a comment.
This revision is now accepted and ready to land.

Thanks, LGTM.


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

https://reviews.llvm.org/D70256



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


[PATCH] D70256: [FPEnv] clang support for constrained FP builtins

2019-12-10 Thread Kevin P. Neal via Phabricator via cfe-commits
kpn updated this revision to Diff 233073.
kpn added a comment.

Update for review comments.


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

https://reviews.llvm.org/D70256

Files:
  clang/lib/CodeGen/CGBuiltin.cpp
  clang/test/CodeGen/constrained-math-builtins.c
  llvm/include/llvm/IR/IRBuilder.h

Index: llvm/include/llvm/IR/IRBuilder.h
===
--- llvm/include/llvm/IR/IRBuilder.h
+++ llvm/include/llvm/IR/IRBuilder.h
@@ -2087,6 +2087,8 @@
 case Intrinsic::experimental_constrained_fpext:
 case Intrinsic::experimental_constrained_fptoui:
 case Intrinsic::experimental_constrained_fptosi:
+case Intrinsic::experimental_constrained_lround:
+case Intrinsic::experimental_constrained_llround:
   C = CreateIntrinsic(ID, {DestTy, V->getType()}, {V, ExceptV}, nullptr,
   Name);
   break;
@@ -2297,6 +2299,37 @@
 Args, OpBundles, Name, FPMathTag);
   }
 
+  // Deprecated [opaque pointer types]
+  CallInst *CreateConstrainedFPCall(
+  Value *Callee, ArrayRef Args, const Twine  = "",
+  Optional Rounding = None,
+  Optional Except = None) {
+llvm::SmallVector UseArgs;
+
+for (auto *OneArg : Args)
+  UseArgs.push_back(OneArg);
+Function *F = cast(Callee);
+switch (F->getIntrinsicID()) {
+default:
+  UseArgs.push_back(getConstrainedFPRounding(Rounding));
+  break;
+case Intrinsic::experimental_constrained_fpext:
+case Intrinsic::experimental_constrained_fptoui:
+case Intrinsic::experimental_constrained_fptosi:
+case Intrinsic::experimental_constrained_lround:
+case Intrinsic::experimental_constrained_llround:
+  // No rounding metadata for these intrinsics.
+  break;
+}
+UseArgs.push_back(getConstrainedFPExcept(Except));
+
+CallInst *C = CreateCall(
+cast(Callee->getType()->getPointerElementType()), Callee,
+UseArgs, Name);
+setConstrainedFPCallAttr(C);
+return C;
+  }
+
   Value *CreateSelect(Value *C, Value *True, Value *False,
   const Twine  = "", Instruction *MDFrom = nullptr) {
 if (auto *CC = dyn_cast(C))
Index: clang/test/CodeGen/constrained-math-builtins.c
===
--- /dev/null
+++ clang/test/CodeGen/constrained-math-builtins.c
@@ -0,0 +1,150 @@
+// RUN: %clang_cc1 -triple x86_64-linux -ffp-exception-behavior=strict -w -S -o - -emit-llvm %s | FileCheck %s
+
+// Test codegen of constrained math builtins.
+
+void foo(double *d, float f, float *fp, long double *l, int *i, const char *c) {
+  f = __builtin_fmod(f,f);f = __builtin_fmodf(f,f);   f =  __builtin_fmodl(f,f);
+
+// CHECK: declare double @llvm.experimental.constrained.frem.f64(double, double, metadata, metadata)
+// CHECK: declare float @llvm.experimental.constrained.frem.f32(float, float, metadata, metadata)
+// CHECK: declare x86_fp80 @llvm.experimental.constrained.frem.f80(x86_fp80, x86_fp80, metadata, metadata)
+
+  __builtin_pow(f,f);__builtin_powf(f,f);   __builtin_powl(f,f);
+
+// CHECK: declare double @llvm.experimental.constrained.pow.f64(double, double, metadata, metadata)
+// CHECK: declare float @llvm.experimental.constrained.pow.f32(float, float, metadata, metadata)
+// CHECK: declare x86_fp80 @llvm.experimental.constrained.pow.f80(x86_fp80, x86_fp80, metadata, metadata)
+
+  __builtin_powi(f,f);__builtin_powif(f,f);   __builtin_powil(f,f);
+
+// CHECK: declare double @llvm.experimental.constrained.powi.f64(double, i32, metadata, metadata)
+// CHECK: declare float @llvm.experimental.constrained.powi.f32(float, i32, metadata, metadata)
+// CHECK: declare x86_fp80 @llvm.experimental.constrained.powi.f80(x86_fp80, i32, metadata, metadata)
+
+  __builtin_ceil(f);   __builtin_ceilf(f);  __builtin_ceill(f);
+
+// CHECK: declare double @llvm.experimental.constrained.ceil.f64(double, metadata, metadata)
+// CHECK: declare float @llvm.experimental.constrained.ceil.f32(float, metadata, metadata)
+// CHECK: declare x86_fp80 @llvm.experimental.constrained.ceil.f80(x86_fp80, metadata, metadata)
+
+  __builtin_cos(f);__builtin_cosf(f);   __builtin_cosl(f); 
+
+// CHECK: declare double @llvm.experimental.constrained.cos.f64(double, metadata, metadata)
+// CHECK: declare float @llvm.experimental.constrained.cos.f32(float, metadata, metadata)
+// CHECK: declare x86_fp80 @llvm.experimental.constrained.cos.f80(x86_fp80, metadata, metadata)
+
+  __builtin_exp(f);__builtin_expf(f);   __builtin_expl(f);
+
+// CHECK: declare double @llvm.experimental.constrained.exp.f64(double, metadata, metadata)
+// CHECK: declare float @llvm.experimental.constrained.exp.f32(float, metadata, metadata)
+// CHECK: declare x86_fp80 @llvm.experimental.constrained.exp.f80(x86_fp80, metadata, metadata)
+
+  __builtin_exp2(f);   __builtin_exp2f(f);  __builtin_exp2l(f); 
+
+// CHECK: declare double 

[PATCH] D70256: [FPEnv] clang support for constrained FP builtins

2019-11-18 Thread John McCall via Phabricator via cfe-commits
rjmccall added inline comments.



Comment at: clang/lib/CodeGen/CGBuiltin.cpp:357
+
+  if (ConstrainedIntrinsicID != Intrinsic::not_intrinsic &&
+  CGF.Builder.getIsFPConstrained()) {

kpn wrote:
> rjmccall wrote:
> > I don't see any situation where `not_intrinsic` is passed in here; why all 
> > these checks?
> I tend to be conservative, and I'm not good at predicting the future. I can 
> remove the checks easily in the next round.
I just can't imagine why you would ever call this function without a 
constrained intrinsic ID when its only purpose is to choose between a 
constrained and unconstrained intrinsic.  It's always better to start with 
stronger preconditions and then generalize later if necessary.



Comment at: clang/lib/CodeGen/CGBuiltin.cpp:2302
+  return RValue::get(Builder.CreateCall(F, {Base, Exponent}));
+}
   }

kpn wrote:
> rjmccall wrote:
> > What can this not use the standard path?
> I'll take another look. It wasn't using the standard path before so I made my 
> added code match. If it can use the standard path in both cases then maybe it 
> should?
Yeah.  It's possible the type-heterogeneity (the power always being an `int`) 
stops that from working for some reason, but if not, it's always nicer to 
re-use more code.


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D70256



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


[PATCH] D70256: [FPEnv] clang support for constrained FP builtins

2019-11-18 Thread Kevin P. Neal via Phabricator via cfe-commits
kpn marked 2 inline comments as done.
kpn added inline comments.



Comment at: clang/lib/CodeGen/CGBuiltin.cpp:357
+
+  if (ConstrainedIntrinsicID != Intrinsic::not_intrinsic &&
+  CGF.Builder.getIsFPConstrained()) {

rjmccall wrote:
> I don't see any situation where `not_intrinsic` is passed in here; why all 
> these checks?
I tend to be conservative, and I'm not good at predicting the future. I can 
remove the checks easily in the next round.



Comment at: clang/lib/CodeGen/CGBuiltin.cpp:2302
+  return RValue::get(Builder.CreateCall(F, {Base, Exponent}));
+}
   }

rjmccall wrote:
> What can this not use the standard path?
I'll take another look. It wasn't using the standard path before so I made my 
added code match. If it can use the standard path in both cases then maybe it 
should?


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D70256



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


[PATCH] D70256: [FPEnv] clang support for constrained FP builtins

2019-11-18 Thread Kevin P. Neal via Phabricator via cfe-commits
kpn added a comment.

D62731  is required for testing this patch.


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D70256



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


[PATCH] D70256: [FPEnv] clang support for constrained FP builtins

2019-11-16 Thread John McCall via Phabricator via cfe-commits
rjmccall added inline comments.



Comment at: clang/lib/CodeGen/CGBuiltin.cpp:357
+
+  if (ConstrainedIntrinsicID != Intrinsic::not_intrinsic &&
+  CGF.Builder.getIsFPConstrained()) {

I don't see any situation where `not_intrinsic` is passed in here; why all 
these checks?



Comment at: clang/lib/CodeGen/CGBuiltin.cpp:2302
+  return RValue::get(Builder.CreateCall(F, {Base, Exponent}));
+}
   }

What can this not use the standard path?


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D70256



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


[PATCH] D70256: [FPEnv] clang support for constrained FP builtins

2019-11-14 Thread Kevin P. Neal via Phabricator via cfe-commits
kpn created this revision.
kpn added reviewers: rjmccall, dblaikie.
Herald added projects: clang, LLVM.
Herald added a subscriber: llvm-commits.

Currently if constrained fp math is requested clang is still emitting calls to 
the non-constrained versions of math builtins. This patch corrects that for 
calls that are not target-specific.

I really wanted to keep constrained/non-constrained decisions in the IRBuilder, 
but that causes complications. This version stays close to that ideal without 
the complications.


Repository:
  rG LLVM Github Monorepo

https://reviews.llvm.org/D70256

Files:
  clang/lib/CodeGen/CGBuiltin.cpp
  clang/test/CodeGen/constrained-math-builtins.c
  llvm/include/llvm/IR/IRBuilder.h

Index: llvm/include/llvm/IR/IRBuilder.h
===
--- llvm/include/llvm/IR/IRBuilder.h
+++ llvm/include/llvm/IR/IRBuilder.h
@@ -2096,6 +2096,8 @@
 case Intrinsic::experimental_constrained_fpext:
 case Intrinsic::experimental_constrained_fptoui:
 case Intrinsic::experimental_constrained_fptosi:
+case Intrinsic::experimental_constrained_lround:
+case Intrinsic::experimental_constrained_llround:
   C = CreateIntrinsic(ID, {DestTy, V->getType()}, {V, ExceptV}, nullptr,
   Name);
   break;
@@ -2306,6 +2308,37 @@
 Args, OpBundles, Name, FPMathTag);
   }
 
+  // Deprecated [opaque pointer types]
+  CallInst *CreateConstrainedFPCall(
+  Value *Callee, ArrayRef Args, const Twine  = "",
+  Optional Rounding = None,
+  Optional Except = None) {
+llvm::SmallVector UseArgs;
+
+for (auto *OneArg : Args)
+  UseArgs.push_back(OneArg);
+Function *F = cast(Callee);
+switch (F->getIntrinsicID()) {
+default:
+  UseArgs.push_back(getConstrainedFPRounding(Rounding));
+  break;
+case Intrinsic::experimental_constrained_fpext:
+case Intrinsic::experimental_constrained_fptoui:
+case Intrinsic::experimental_constrained_fptosi:
+case Intrinsic::experimental_constrained_lround:
+case Intrinsic::experimental_constrained_llround:
+  // No rounding metadata for these intrinsics.
+  break;
+}
+UseArgs.push_back(getConstrainedFPExcept(Except));
+
+CallInst *C = CreateCall(
+cast(Callee->getType()->getPointerElementType()), Callee,
+UseArgs, Name);
+setConstrainedFPCallAttr(C);
+return C;
+  }
+
   Value *CreateSelect(Value *C, Value *True, Value *False,
   const Twine  = "", Instruction *MDFrom = nullptr) {
 if (auto *CC = dyn_cast(C))
Index: clang/test/CodeGen/constrained-math-builtins.c
===
--- /dev/null
+++ clang/test/CodeGen/constrained-math-builtins.c
@@ -0,0 +1,150 @@
+// RUN: %clang_cc1 -triple x86_64-linux -ffp-exception-behavior=strict -w -S -o - -emit-llvm %s | FileCheck %s
+
+// Test codegen of constrained math builtins.
+
+void foo(double *d, float f, float *fp, long double *l, int *i, const char *c) {
+  f = __builtin_fmod(f,f);f = __builtin_fmodf(f,f);   f =  __builtin_fmodl(f,f);
+
+// CHECK: declare double @llvm.experimental.constrained.frem.f64(double, double, metadata, metadata)
+// CHECK: declare float @llvm.experimental.constrained.frem.f32(float, float, metadata, metadata)
+// CHECK: declare x86_fp80 @llvm.experimental.constrained.frem.f80(x86_fp80, x86_fp80, metadata, metadata)
+
+  __builtin_pow(f,f);__builtin_powf(f,f);   __builtin_powl(f,f);
+
+// CHECK: declare double @llvm.experimental.constrained.pow.f64(double, double, metadata, metadata)
+// CHECK: declare float @llvm.experimental.constrained.pow.f32(float, float, metadata, metadata)
+// CHECK: declare x86_fp80 @llvm.experimental.constrained.pow.f80(x86_fp80, x86_fp80, metadata, metadata)
+
+  __builtin_powi(f,f);__builtin_powif(f,f);   __builtin_powil(f,f);
+
+// CHECK: declare double @llvm.experimental.constrained.powi.f64(double, i32, metadata, metadata)
+// CHECK: declare float @llvm.experimental.constrained.powi.f32(float, i32, metadata, metadata)
+// CHECK: declare x86_fp80 @llvm.experimental.constrained.powi.f80(x86_fp80, i32, metadata, metadata)
+
+  __builtin_ceil(f);   __builtin_ceilf(f);  __builtin_ceill(f);
+
+// CHECK: declare double @llvm.experimental.constrained.ceil.f64(double, metadata, metadata)
+// CHECK: declare float @llvm.experimental.constrained.ceil.f32(float, metadata, metadata)
+// CHECK: declare x86_fp80 @llvm.experimental.constrained.ceil.f80(x86_fp80, metadata, metadata)
+
+  __builtin_cos(f);__builtin_cosf(f);   __builtin_cosl(f); 
+
+// CHECK: declare double @llvm.experimental.constrained.cos.f64(double, metadata, metadata)
+// CHECK: declare float @llvm.experimental.constrained.cos.f32(float, metadata, metadata)
+// CHECK: declare x86_fp80 @llvm.experimental.constrained.cos.f80(x86_fp80, metadata, metadata)
+
+  __builtin_exp(f);__builtin_expf(f);