[PATCH] D78827: Add support for #pragma clang fp reassociate(on|off) -- floating point control of associative math transformations

2020-05-06 Thread Steve Canon via Phabricator via cfe-commits
scanon added a comment.

TS18661-5 is quite vague on what the intended semantics for the pragma are.

These pragmas are intended to be bindings of clause 10.4 of IEEE 754, which is 
also pretty wishy-washy on the whole, but it's worth noting that clause 10 is 
titled *expression evaluation* specifically. The relevant text here is:

> A language standard should also define, and require implementations to 
> provide, attributes that allow and disallow value-changing optimizations, 
> separately or collectively, for a block. These optimizations might include, 
> but are not limited to:
>  ― Applying the associative or distributive laws.
>  ― Synthesis of a fusedMultiplyAdd operation from a multiplication and an 
> addition.
>  ― Synthesis of a formatOf operation from an operation and a conversion of 
> the result of the 40 operation.
>  ― Use of wider intermediate results in expression evaluation.

So IEEE-754 appears to view this as being "just like" contraction. (Note that 
this is all under a "should", so #yolo).


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D78827



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


[PATCH] D78827: Add support for #pragma clang fp reassociate(on|off) -- floating point control of associative math transformations

2020-05-06 Thread Melanie Blower via Phabricator via cfe-commits
mibintc added a comment.

The ISO C proposal is here 
http://www.open-std.org/jtc1/sc22/wg14/www/docs/n2407.pdf but the details are 
in the IEEE standards documents.


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D78827



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


[PATCH] D78827: Add support for #pragma clang fp reassociate(on|off) -- floating point control of associative math transformations

2020-05-06 Thread John McCall via Phabricator via cfe-commits
rjmccall added a comment.

That's actually really interesting.  Is there a paper describing the desired 
model in more detail?

I think the natural interpretation of this pragma is to say that the specific 
operations written within the pragma are considered to be associative and are 
therefore allowed to be re-associated with other associative operators.  
However, that might not be the committee's formal interpretation, given how 
contraction works.


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D78827



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


[PATCH] D78827: Add support for #pragma clang fp reassociate(on|off) -- floating point control of associative math transformations

2020-05-06 Thread Melanie Blower via Phabricator via cfe-commits
mibintc added a comment.

BTW there is a proposal 
http://www.open-std.org/jtc1/sc22/wg14/www/docs/n2421.pdf at the ISO C meeting 
to support some new floating point pragmas including 
#pragma STDC FENV_ALLOW_ASSOCIATIVE_LAW on-off-switch
The committee wants to see an implementation(s) to ensure that it's viable.


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D78827



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


[PATCH] D78827: Add support for #pragma clang fp reassociate(on|off) -- floating point control of associative math transformations

2020-05-06 Thread Melanie Blower via Phabricator via cfe-commits
This revision was automatically updated to reflect the committed changes.
Closed by commit rGc355bec749e9: Add support for #pragma clang fp 
reassociate(on|off) (authored by mibintc).

Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D78827

Files:
  clang/docs/LanguageExtensions.rst
  clang/include/clang/Basic/DiagnosticParseKinds.td
  clang/include/clang/Basic/LangOptions.def
  clang/include/clang/Basic/LangOptions.h
  clang/include/clang/Sema/Sema.h
  clang/lib/CodeGen/BackendUtil.cpp
  clang/lib/Frontend/CompilerInvocation.cpp
  clang/lib/Parse/ParsePragma.cpp
  clang/lib/Sema/SemaAttr.cpp
  clang/test/CodeGen/fp-reassoc-pragma.cpp
  clang/test/Parser/pragma-fp-contract.c
  clang/test/Parser/pragma-fp.cpp

Index: clang/test/Parser/pragma-fp.cpp
===
--- clang/test/Parser/pragma-fp.cpp
+++ clang/test/Parser/pragma-fp.cpp
@@ -1,14 +1,14 @@
 // RUN: %clang_cc1 -std=c++11 -verify %s
 
 void test_0(int *List, int Length) {
-/* expected-error@+1 {{missing option; expected contract}} */
+/* expected-error@+1 {{missing option; expected 'contract' or 'reassociate'}} */
 #pragma clang fp
   for (int i = 0; i < Length; i++) {
 List[i] = i;
   }
 }
 void test_1(int *List, int Length) {
-/* expected-error@+1 {{invalid option 'blah'; expected contract}} */
+/* expected-error@+1 {{invalid option 'blah'; expected 'contract' or 'reassociate'}} */
 #pragma clang fp blah
   for (int i = 0; i < Length; i++) {
 List[i] = i;
@@ -24,7 +24,7 @@
 }
 
 void test_4(int *List, int Length) {
-/* expected-error@+1 {{unexpected argument 'while' to '#pragma clang fp contract'; expected 'on', 'fast' or 'off'}} */
+/* expected-error@+1 {{unexpected argument 'while' to '#pragma clang fp contract'; expected 'fast' or 'on' or 'off'}} */
 #pragma clang fp contract(while)
   for (int i = 0; i < Length; i++) {
 List[i] = i;
@@ -32,7 +32,7 @@
 }
 
 void test_5(int *List, int Length) {
-/* expected-error@+1 {{unexpected argument 'maybe' to '#pragma clang fp contract'; expected 'on', 'fast' or 'off'}} */
+/* expected-error@+1 {{unexpected argument 'maybe' to '#pragma clang fp contract'; expected 'fast' or 'on' or 'off'}} */
 #pragma clang fp contract(maybe)
   for (int i = 0; i < Length; i++) {
 List[i] = i;
Index: clang/test/Parser/pragma-fp-contract.c
===
--- clang/test/Parser/pragma-fp-contract.c
+++ clang/test/Parser/pragma-fp-contract.c
@@ -23,3 +23,18 @@
 // expected-error@+1 {{this pragma cannot appear in union declaration}}
 #pragma STDC FP_CONTRACT ON
 };
+
+float fp_reassoc_fail(float a, float b) {
+  // CHECK-LABEL: fp_reassoc_fail
+  // expected-error@+2{{'#pragma clang fp' can only appear at file scope or at the start of a compound statement}}
+  float c = a + b;
+#pragma clang fp reassociate(off)
+  return c - b;
+}
+
+float fp_reassoc_no_fast(float a, float b) {
+// CHECK-LABEL: fp_reassoc_no_fast
+// expected-error@+1{{unexpected argument 'fast' to '#pragma clang fp reassociate'; expected 'on' or 'off'}}
+#pragma clang fp reassociate(fast)
+  return a - b;
+}
Index: clang/test/CodeGen/fp-reassoc-pragma.cpp
===
--- /dev/null
+++ clang/test/CodeGen/fp-reassoc-pragma.cpp
@@ -0,0 +1,92 @@
+// RUN: %clang_cc1 -O3 -triple %itanium_abi_triple -emit-llvm -o - %s | FileCheck %s
+// Simple case
+float fp_reassoc_simple(float a, float b, float c) {
+// CHECK: _Z17fp_reassoc_simplefff
+// CHECK: %[[A:.+]] = fadd reassoc float %b, %c
+// CHECK: %[[M:.+]] = fmul reassoc float %[[A]], %b
+// CHECK-NEXT: fadd reassoc float %[[M]], %c
+#pragma clang fp reassociate(on)
+  a = b + c;
+  return a * b + c;
+}
+
+// Reassoc pragma should only apply to its scope
+float fp_reassoc_scoped(float a, float b, float c) {
+  // CHECK: _Z17fp_reassoc_scopedfff
+  // CHECK: %[[M:.+]] = fmul float %a, %b
+  // CHECK-NEXT: fadd float %[[M]], %c
+  {
+#pragma clang fp reassociate(on)
+  }
+  return a * b + c;
+}
+
+// Reassoc pragma should apply to templates as well
+class Foo {};
+Foo operator+(Foo, Foo);
+template 
+T template_reassoc(T a, T b, T c) {
+#pragma clang fp reassociate(on)
+  return ((a + b) - c) + c;
+}
+
+float fp_reassoc_template(float a, float b, float c) {
+  // CHECK: _Z19fp_reassoc_templatefff
+  // CHECK: %[[A1:.+]] = fadd reassoc float %a, %b
+  // CHECK-NEXT: %[[A2:.+]] = fsub reassoc float %[[A1]], %c
+  // CHECK-NEXT: fadd reassoc float %[[A2]], %c
+  return template_reassoc(a, b, c);
+}
+
+// File Scoping should work across functions
+#pragma clang fp reassociate(on)
+float fp_file_scope_on(float a, float b, float c) {
+  // CHECK: _Z16fp_file_scope_onfff
+  // CHECK: %[[M1:.+]] = fmul reassoc float %a, %c
+  // CHECK-NEXT: %[[M2:.+]] = fmul reassoc float %b, %c
+  // CHECK-NEXT: fadd reassoc float %[[M1]], %[[M2]]
+  return (a * c) + (b * c);
+}
+
+// 

[PATCH] D78827: Add support for #pragma clang fp reassociate(on|off) -- floating point control of associative math transformations

2020-05-05 Thread John McCall via Phabricator via cfe-commits
rjmccall accepted this revision.
rjmccall added a comment.

LGTM, too.  Thanks!


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D78827



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


[PATCH] D78827: Add support for #pragma clang fp reassociate(on|off) -- floating point control of associative math transformations

2020-05-05 Thread Steve Canon via Phabricator via cfe-commits
scanon accepted this revision.
scanon added a comment.
This revision is now accepted and ready to land.

My concerns have been addressed. Thanks for bearing with me, Melanie!


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D78827



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


[PATCH] D78827: Add support for #pragma clang fp reassociate(on|off) -- floating point control of associative math transformations

2020-05-05 Thread Steve Canon via Phabricator via cfe-commits
scanon added a comment.

(Please get one additional sign off before committing; I'm mainly signing off 
on the numerics model aspect).


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D78827



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


[PATCH] D78827: Add support for #pragma clang fp reassociate(on|off) -- floating point control of associative math transformations

2020-05-05 Thread Melanie Blower via Phabricator via cfe-commits
mibintc updated this revision to Diff 262217.
mibintc retitled this revision from "Add support for #pragma clang fp 
reassociate(fast|off) -- floating point control of associative math 
transformations" to "Add support for #pragma clang fp reassociate(on|off) -- 
floating point control of associative math transformations".
mibintc edited the summary of this revision.
mibintc added a comment.

Here it is again with the on/off spelling


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D78827

Files:
  clang/docs/LanguageExtensions.rst
  clang/include/clang/Basic/DiagnosticParseKinds.td
  clang/include/clang/Basic/LangOptions.def
  clang/include/clang/Basic/LangOptions.h
  clang/include/clang/Sema/Sema.h
  clang/lib/CodeGen/BackendUtil.cpp
  clang/lib/Frontend/CompilerInvocation.cpp
  clang/lib/Parse/ParsePragma.cpp
  clang/lib/Sema/SemaAttr.cpp
  clang/test/CodeGen/fp-reassoc-pragma.cpp
  clang/test/Parser/pragma-fp-contract.c
  clang/test/Parser/pragma-fp.cpp

Index: clang/test/Parser/pragma-fp.cpp
===
--- clang/test/Parser/pragma-fp.cpp
+++ clang/test/Parser/pragma-fp.cpp
@@ -1,14 +1,14 @@
 // RUN: %clang_cc1 -std=c++11 -verify %s
 
 void test_0(int *List, int Length) {
-/* expected-error@+1 {{missing option; expected contract}} */
+/* expected-error@+1 {{missing option; expected 'contract' or 'reassociate'}} */
 #pragma clang fp
   for (int i = 0; i < Length; i++) {
 List[i] = i;
   }
 }
 void test_1(int *List, int Length) {
-/* expected-error@+1 {{invalid option 'blah'; expected contract}} */
+/* expected-error@+1 {{invalid option 'blah'; expected 'contract' or 'reassociate'}} */
 #pragma clang fp blah
   for (int i = 0; i < Length; i++) {
 List[i] = i;
@@ -24,7 +24,7 @@
 }
 
 void test_4(int *List, int Length) {
-/* expected-error@+1 {{unexpected argument 'while' to '#pragma clang fp contract'; expected 'on', 'fast' or 'off'}} */
+/* expected-error@+1 {{unexpected argument 'while' to '#pragma clang fp contract'; expected 'fast' or 'on' or 'off'}} */
 #pragma clang fp contract(while)
   for (int i = 0; i < Length; i++) {
 List[i] = i;
@@ -32,7 +32,7 @@
 }
 
 void test_5(int *List, int Length) {
-/* expected-error@+1 {{unexpected argument 'maybe' to '#pragma clang fp contract'; expected 'on', 'fast' or 'off'}} */
+/* expected-error@+1 {{unexpected argument 'maybe' to '#pragma clang fp contract'; expected 'fast' or 'on' or 'off'}} */
 #pragma clang fp contract(maybe)
   for (int i = 0; i < Length; i++) {
 List[i] = i;
Index: clang/test/Parser/pragma-fp-contract.c
===
--- clang/test/Parser/pragma-fp-contract.c
+++ clang/test/Parser/pragma-fp-contract.c
@@ -23,3 +23,18 @@
 // expected-error@+1 {{this pragma cannot appear in union declaration}}
 #pragma STDC FP_CONTRACT ON
 };
+
+float fp_reassoc_fail(float a, float b) {
+  // CHECK-LABEL: fp_reassoc_fail
+  // expected-error@+2{{'#pragma clang fp' can only appear at file scope or at the start of a compound statement}}
+  float c = a + b;
+#pragma clang fp reassociate(off)
+  return c - b;
+}
+
+float fp_reassoc_no_fast(float a, float b) {
+// CHECK-LABEL: fp_reassoc_no_fast
+// expected-error@+1{{unexpected argument 'fast' to '#pragma clang fp reassociate'; expected 'on' or 'off'}}
+#pragma clang fp reassociate(fast)
+  return a - b;
+}
Index: clang/test/CodeGen/fp-reassoc-pragma.cpp
===
--- /dev/null
+++ clang/test/CodeGen/fp-reassoc-pragma.cpp
@@ -0,0 +1,92 @@
+// RUN: %clang_cc1 -O3 -triple %itanium_abi_triple -emit-llvm -o - %s | FileCheck %s
+// Simple case
+float fp_reassoc_simple(float a, float b, float c) {
+// CHECK: _Z17fp_reassoc_simplefff
+// CHECK: %[[A:.+]] = fadd reassoc float %b, %c
+// CHECK: %[[M:.+]] = fmul reassoc float %[[A]], %b
+// CHECK-NEXT: fadd reassoc float %[[M]], %c
+#pragma clang fp reassociate(on)
+  a = b + c;
+  return a * b + c;
+}
+
+// Reassoc pragma should only apply to its scope
+float fp_reassoc_scoped(float a, float b, float c) {
+  // CHECK: _Z17fp_reassoc_scopedfff
+  // CHECK: %[[M:.+]] = fmul float %a, %b
+  // CHECK-NEXT: fadd float %[[M]], %c
+  {
+#pragma clang fp reassociate(on)
+  }
+  return a * b + c;
+}
+
+// Reassoc pragma should apply to templates as well
+class Foo {};
+Foo operator+(Foo, Foo);
+template 
+T template_reassoc(T a, T b, T c) {
+#pragma clang fp reassociate(on)
+  return ((a + b) - c) + c;
+}
+
+float fp_reassoc_template(float a, float b, float c) {
+  // CHECK: _Z19fp_reassoc_templatefff
+  // CHECK: %[[A1:.+]] = fadd reassoc float %a, %b
+  // CHECK-NEXT: %[[A2:.+]] = fsub reassoc float %[[A1]], %c
+  // CHECK-NEXT: fadd reassoc float %[[A2]], %c
+  return template_reassoc(a, b, c);
+}
+
+// File Scoping should work across functions
+#pragma clang fp reassociate(on)
+float fp_file_scope_on(float a, 

[PATCH] D78827: Add support for #pragma clang fp reassociate(fast|off) -- floating point control of associative math transformations

2020-05-05 Thread John McCall via Phabricator via cfe-commits
rjmccall added a comment.

That makes sense, thanks.  I think I'm comfortable using on/off for this, but 
it's definitely good to stop and consider, and you're absolutely right that it 
needs to be documented.


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D78827



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


[PATCH] D78827: Add support for #pragma clang fp reassociate(fast|off) -- floating point control of associative math transformations

2020-05-05 Thread Steve Canon via Phabricator via cfe-commits
scanon added a comment.

> I don't think the C standard is likely to ever bless reassociative FP math 
> with an expression-local restriction. Steve, do you actually think that would 
> be a useful optimization mode?

I think it's pretty unlikely that C would do this, as well. It is plausibly a 
useful semantic mode, but I don't know that we need to reserve the name for it. 
I only want to raise the question, and be sure that we're aware that we're 
making a decision here (also, either way we need to document it clearly).


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D78827



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


[PATCH] D78827: Add support for #pragma clang fp reassociate(fast|off) -- floating point control of associative math transformations

2020-05-05 Thread John McCall via Phabricator via cfe-commits
rjmccall added a comment.

The reason we call FP contraction "fast" instead of "on" when it's 
cross-statement is because "on" is supposed to be consistent with the C 
language rules, whereas "fast" is stronger.  There's no analogous situation 
with reassociation; I don't think the C standard is likely to ever bless 
reassociative FP math with an expression-local restriction.  Steve, do you 
actually think that would be a useful optimization mode?


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D78827



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


[PATCH] D78827: Add support for #pragma clang fp reassociate(fast|off) -- floating point control of associative math transformations

2020-05-05 Thread Melanie Blower via Phabricator via cfe-commits
mibintc added a comment.

I checked with FPGA folks and confirm what @scanon says is correct, the reassoc 
fast math flag enables reassociation across multiple statements, so i changed 
the syntax to use 'fast' and 'off', and changed the documentation


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D78827



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


[PATCH] D78827: Add support for #pragma clang fp reassociate(fast|off) -- floating point control of associative math transformations

2020-05-05 Thread Melanie Blower via Phabricator via cfe-commits
mibintc updated this revision to Diff 262108.
mibintc retitled this revision from "Add support for #pragma clang fp 
reassociate(on|off) -- floating point control of associative math 
transformations" to "Add support for #pragma clang fp reassociate(fast|off) -- 
floating point control of associative math transformations".
mibintc edited the summary of this revision.

Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D78827

Files:
  clang/docs/LanguageExtensions.rst
  clang/include/clang/Basic/DiagnosticParseKinds.td
  clang/include/clang/Basic/LangOptions.def
  clang/include/clang/Basic/LangOptions.h
  clang/include/clang/Sema/Sema.h
  clang/lib/CodeGen/BackendUtil.cpp
  clang/lib/Frontend/CompilerInvocation.cpp
  clang/lib/Parse/ParsePragma.cpp
  clang/lib/Sema/SemaAttr.cpp
  clang/test/CodeGen/fp-reassoc-pragma.cpp
  clang/test/Parser/pragma-fp-contract.c
  clang/test/Parser/pragma-fp.cpp

Index: clang/test/Parser/pragma-fp.cpp
===
--- clang/test/Parser/pragma-fp.cpp
+++ clang/test/Parser/pragma-fp.cpp
@@ -1,14 +1,14 @@
 // RUN: %clang_cc1 -std=c++11 -verify %s
 
 void test_0(int *List, int Length) {
-/* expected-error@+1 {{missing option; expected contract}} */
+/* expected-error@+1 {{missing option; expected 'contract' or 'reassociate'}} */
 #pragma clang fp
   for (int i = 0; i < Length; i++) {
 List[i] = i;
   }
 }
 void test_1(int *List, int Length) {
-/* expected-error@+1 {{invalid option 'blah'; expected contract}} */
+/* expected-error@+1 {{invalid option 'blah'; expected 'contract' or 'reassociate'}} */
 #pragma clang fp blah
   for (int i = 0; i < Length; i++) {
 List[i] = i;
@@ -24,7 +24,7 @@
 }
 
 void test_4(int *List, int Length) {
-/* expected-error@+1 {{unexpected argument 'while' to '#pragma clang fp contract'; expected 'on', 'fast' or 'off'}} */
+/* expected-error@+1 {{unexpected argument 'while' to '#pragma clang fp contract'; expected 'fast' or 'on' or 'off'}} */
 #pragma clang fp contract(while)
   for (int i = 0; i < Length; i++) {
 List[i] = i;
@@ -32,7 +32,7 @@
 }
 
 void test_5(int *List, int Length) {
-/* expected-error@+1 {{unexpected argument 'maybe' to '#pragma clang fp contract'; expected 'on', 'fast' or 'off'}} */
+/* expected-error@+1 {{unexpected argument 'maybe' to '#pragma clang fp contract'; expected 'fast' or 'on' or 'off'}} */
 #pragma clang fp contract(maybe)
   for (int i = 0; i < Length; i++) {
 List[i] = i;
Index: clang/test/Parser/pragma-fp-contract.c
===
--- clang/test/Parser/pragma-fp-contract.c
+++ clang/test/Parser/pragma-fp-contract.c
@@ -23,3 +23,18 @@
 // expected-error@+1 {{this pragma cannot appear in union declaration}}
 #pragma STDC FP_CONTRACT ON
 };
+
+float fp_reassoc_fail(float a, float b) {
+  // CHECK-LABEL: fp_reassoc_fail
+  // expected-error@+2{{'#pragma clang fp' can only appear at file scope or at the start of a compound statement}}
+  float c = a + b;
+#pragma clang fp reassociate(fast)
+  return c - b;
+}
+
+float fp_reassoc_no_fast(float a, float b) {
+// CHECK-LABEL: fp_reassoc_no_on
+// expected-error@+1{{unexpected argument 'on' to '#pragma clang fp reassociate'; expected 'fast' or 'off'}}
+#pragma clang fp reassociate(on)
+  return a - b;
+}
Index: clang/test/CodeGen/fp-reassoc-pragma.cpp
===
--- /dev/null
+++ clang/test/CodeGen/fp-reassoc-pragma.cpp
@@ -0,0 +1,92 @@
+// RUN: %clang_cc1 -O3 -triple %itanium_abi_triple -emit-llvm -o - %s | FileCheck %s
+// Simple case
+float fp_reassoc_simple(float a, float b, float c) {
+// CHECK: _Z17fp_reassoc_simplefff
+// CHECK: %[[A:.+]] = fadd reassoc float %b, %c
+// CHECK: %[[M:.+]] = fmul reassoc float %[[A]], %b
+// CHECK-NEXT: fadd reassoc float %[[M]], %c
+#pragma clang fp reassociate(fast)
+  a = b + c;
+  return a * b + c;
+}
+
+// Reassoc pragma should only apply to its scope
+float fp_reassoc_scoped(float a, float b, float c) {
+  // CHECK: _Z17fp_reassoc_scopedfff
+  // CHECK: %[[M:.+]] = fmul float %a, %b
+  // CHECK-NEXT: fadd float %[[M]], %c
+  {
+#pragma clang fp reassociate(fast)
+  }
+  return a * b + c;
+}
+
+// Reassoc pragma should apply to templates as well
+class Foo {};
+Foo operator+(Foo, Foo);
+template 
+T template_reassoc(T a, T b, T c) {
+#pragma clang fp reassociate(fast)
+  return ((a + b) - c) + c;
+}
+
+float fp_reassoc_template(float a, float b, float c) {
+  // CHECK: _Z19fp_reassoc_templatefff
+  // CHECK: %[[A1:.+]] = fadd reassoc float %a, %b
+  // CHECK-NEXT: %[[A2:.+]] = fsub reassoc float %[[A1]], %c
+  // CHECK-NEXT: fadd reassoc float %[[A2]], %c
+  return template_reassoc(a, b, c);
+}
+
+// File Scoping should work across functions
+#pragma clang fp reassociate(fast)
+float fp_file_scope_on(float a, float b, float c) {
+  // CHECK: _Z16fp_file_scope_onfff
+  // 

[PATCH] D78827: Add support for #pragma clang fp reassociate(on|off) -- floating point control of associative math transformations

2020-05-04 Thread Melanie Blower via Phabricator via cfe-commits
mibintc updated this revision to Diff 261921.
mibintc added a comment.

I fixed the issues that @rjmccall mentioned.  I don't yet have an answer for 
@scanon, need to get back to you about that.


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D78827

Files:
  clang/docs/LanguageExtensions.rst
  clang/include/clang/Basic/DiagnosticParseKinds.td
  clang/include/clang/Basic/LangOptions.def
  clang/include/clang/Basic/LangOptions.h
  clang/include/clang/Sema/Sema.h
  clang/lib/CodeGen/BackendUtil.cpp
  clang/lib/Frontend/CompilerInvocation.cpp
  clang/lib/Parse/ParsePragma.cpp
  clang/lib/Sema/SemaAttr.cpp
  clang/test/CodeGen/fp-reassoc-pragma.cpp
  clang/test/Parser/pragma-fp-contract.c
  clang/test/Parser/pragma-fp.cpp

Index: clang/test/Parser/pragma-fp.cpp
===
--- clang/test/Parser/pragma-fp.cpp
+++ clang/test/Parser/pragma-fp.cpp
@@ -1,14 +1,14 @@
 // RUN: %clang_cc1 -std=c++11 -verify %s
 
 void test_0(int *List, int Length) {
-/* expected-error@+1 {{missing option; expected contract}} */
+/* expected-error@+1 {{missing option; expected 'contract' or 'reassociate'}} */
 #pragma clang fp
   for (int i = 0; i < Length; i++) {
 List[i] = i;
   }
 }
 void test_1(int *List, int Length) {
-/* expected-error@+1 {{invalid option 'blah'; expected contract}} */
+/* expected-error@+1 {{invalid option 'blah'; expected 'contract' or 'reassociate'}} */
 #pragma clang fp blah
   for (int i = 0; i < Length; i++) {
 List[i] = i;
@@ -24,7 +24,7 @@
 }
 
 void test_4(int *List, int Length) {
-/* expected-error@+1 {{unexpected argument 'while' to '#pragma clang fp contract'; expected 'on', 'fast' or 'off'}} */
+/* expected-error@+1 {{unexpected argument 'while' to '#pragma clang fp contract'; expected 'fast' or 'on' or 'off'}} */
 #pragma clang fp contract(while)
   for (int i = 0; i < Length; i++) {
 List[i] = i;
@@ -32,7 +32,7 @@
 }
 
 void test_5(int *List, int Length) {
-/* expected-error@+1 {{unexpected argument 'maybe' to '#pragma clang fp contract'; expected 'on', 'fast' or 'off'}} */
+/* expected-error@+1 {{unexpected argument 'maybe' to '#pragma clang fp contract'; expected 'fast' or 'on' or 'off'}} */
 #pragma clang fp contract(maybe)
   for (int i = 0; i < Length; i++) {
 List[i] = i;
Index: clang/test/Parser/pragma-fp-contract.c
===
--- clang/test/Parser/pragma-fp-contract.c
+++ clang/test/Parser/pragma-fp-contract.c
@@ -23,3 +23,18 @@
 // expected-error@+1 {{this pragma cannot appear in union declaration}}
 #pragma STDC FP_CONTRACT ON
 };
+
+float fp_reassoc_fail(float a, float b) {
+  // CHECK-LABEL: fp_reassoc_fail
+  // expected-error@+2{{'#pragma clang fp' can only appear at file scope or at the start of a compound statement}}
+  float c = a + b;
+#pragma clang fp reassociate(on)
+  return c - b;
+}
+
+float fp_reassoc_no_fast(float a, float b) {
+// CHECK-LABEL: fp_reassoc_no_fast
+// expected-error@+1{{unexpected argument 'fast' to '#pragma clang fp reassociate'; expected 'on' or 'off'}}
+#pragma clang fp reassociate(fast)
+  return a - b;
+}
Index: clang/test/CodeGen/fp-reassoc-pragma.cpp
===
--- /dev/null
+++ clang/test/CodeGen/fp-reassoc-pragma.cpp
@@ -0,0 +1,90 @@
+// RUN: %clang_cc1 -O3 -triple %itanium_abi_triple -emit-llvm -o - %s | FileCheck %s
+// Simple case
+float fp_reassoc_simple(float a, float b, float c) {
+// CHECK: _Z17fp_reassoc_simplefff
+// CHECK: %[[M:.+]] = fmul reassoc float %a, %b
+// CHECK-NEXT: fadd reassoc float %[[M]], %c
+#pragma clang fp reassociate(on)
+  return a * b + c;
+}
+
+// Reassoc pragma should only apply to its scope
+float fp_reassoc_scoped(float a, float b, float c) {
+  // CHECK: _Z17fp_reassoc_scopedfff
+  // CHECK: %[[M:.+]] = fmul float %a, %b
+  // CHECK-NEXT: fadd float %[[M]], %c
+  {
+#pragma clang fp reassociate(on)
+  }
+  return a * b + c;
+}
+
+// Reassoc pragma should apply to templates as well
+class Foo {};
+Foo operator+(Foo, Foo);
+template 
+T template_reassoc(T a, T b, T c) {
+#pragma clang fp reassociate(on)
+  return ((a + b) - c) + c;
+}
+
+float fp_reassoc_template(float a, float b, float c) {
+  // CHECK: _Z19fp_reassoc_templatefff
+  // CHECK: %[[A1:.+]] = fadd reassoc float %a, %b
+  // CHECK-NEXT: %[[A2:.+]] = fsub reassoc float %[[A1]], %c
+  // CHECK-NEXT: fadd reassoc float %[[A2]], %c
+  return template_reassoc(a, b, c);
+}
+
+// File Scoping should work across functions
+#pragma clang fp reassociate(on)
+float fp_file_scope_on(float a, float b, float c) {
+  // CHECK: _Z16fp_file_scope_onfff
+  // CHECK: %[[M1:.+]] = fmul reassoc float %a, %c
+  // CHECK-NEXT: %[[M2:.+]] = fmul reassoc float %b, %c
+  // CHECK-NEXT: fadd reassoc float %[[M1]], %[[M2]]
+  return (a * c) + (b * c);
+}
+
+// Inner pragma has precedence
+float 

[PATCH] D78827: Add support for #pragma clang fp reassociate(on|off) -- floating point control of associative math transformations

2020-05-04 Thread Steve Canon via Phabricator via cfe-commits
scanon added inline comments.



Comment at: clang/docs/LanguageExtensions.rst:3182
+enabled for the translation unit with the ``-fassociative-math`` flag.
+The pragma can take two values: ``on`` and ``off``.
+

mibintc wrote:
> scanon wrote:
> > rjmccall wrote:
> > > Do you want to add an example here?
> > Is the intention that this allows reassociation only within statements 
> > (like fp contract on)? Based on the ir in the tests, I think the answer is 
> > "no".
> > 
> > If so, should "on" be called "fast" instead, since its semantics match the 
> > "fast" semantics for contract, and reserve "on" for reassociation within a 
> > statement (that seems like it would also be useful, potentially)?
> > 
> > Otherwise, please add some tests with multiple statements.
> > 
> > I agree with John that `pragma clang fp reassociate` is a reasonable 
> > spelling.
> The intention is that the pragma can be placed at either file scope or at the 
> start of a compound statement, if at file scope it affects the functions 
> following the pragma.  If at compound statement it is effective for the 
> compound statement, i can modify the test to have multiple statements.  I 
> disagree with the suggestion of "fast" instead of on/off.  at the command 
> line you can use -f[no-]associative-math; of course that command line option 
> isn't specific to floating point, but the point is it's on/off ; i can't 
> speak to whether "fast" would be a useful setting.  Thanks for your review
I don't think you understood my comment, so I'll try to explain more clearly: I 
am not asking if it applies to multiple statements or a single statement; I am 
asking within what scope reassociation is allowed.

An example: `fp contract on` allows:
```
double r = a*b + c;
```
to be contracted to an fma, but does not allow:
```
double t = a*b;
double r = t + c;
```
to be contracted. `fp contract fast` allows both to be contracted.

Your reassociate pragma, if I am understanding correctly, allows:
```
double t = a + b;
double r = t + c;
```
to be reassociated; this matches the behavior of `fp contract fast`. I am 
asking if, for the sake of understandability and orthogonality of the 
floating-point model, it would make more sense for this option to be named 
`fast`, reserving `on` for a mode that only allows reassociation within 
expressions.


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D78827



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


[PATCH] D78827: Add support for #pragma clang fp reassociate(on|off) -- floating point control of associative math transformations

2020-05-04 Thread Melanie Blower via Phabricator via cfe-commits
mibintc marked an inline comment as done.
mibintc added a comment.

A reply to @scanon




Comment at: clang/docs/LanguageExtensions.rst:3182
+enabled for the translation unit with the ``-fassociative-math`` flag.
+The pragma can take two values: ``on`` and ``off``.
+

scanon wrote:
> rjmccall wrote:
> > Do you want to add an example here?
> Is the intention that this allows reassociation only within statements (like 
> fp contract on)? Based on the ir in the tests, I think the answer is "no".
> 
> If so, should "on" be called "fast" instead, since its semantics match the 
> "fast" semantics for contract, and reserve "on" for reassociation within a 
> statement (that seems like it would also be useful, potentially)?
> 
> Otherwise, please add some tests with multiple statements.
> 
> I agree with John that `pragma clang fp reassociate` is a reasonable spelling.
The intention is that the pragma can be placed at either file scope or at the 
start of a compound statement, if at file scope it affects the functions 
following the pragma.  If at compound statement it is effective for the 
compound statement, i can modify the test to have multiple statements.  I 
disagree with the suggestion of "fast" instead of on/off.  at the command line 
you can use -f[no-]associative-math; of course that command line option isn't 
specific to floating point, but the point is it's on/off ; i can't speak to 
whether "fast" would be a useful setting.  Thanks for your review


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D78827



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


[PATCH] D78827: Add support for #pragma clang fp reassociate(on|off) -- floating point control of associative math transformations

2020-05-04 Thread John McCall via Phabricator via cfe-commits
rjmccall added a comment.

Just minor requests now.




Comment at: clang/docs/LanguageExtensions.rst:3177
+Both floating point reassociation and floating point contraction can be
+controlled with this pragma.
+``#pragma clang fp reassoc`` allows control over the reassociation

rjmccall wrote:
> Let's go ahead and word this as if arbitrary things will be controllable in 
> the future.  So:
> 
> > Currently, the following things can be controlled by this pragma:
Thanks.  Please put the first sentence in its own paragraph and end it with a 
colon so that it logically leads into both of the following blocks.



Comment at: clang/docs/LanguageExtensions.rst:3182
+enabled for the translation unit with the ``-fassociative-math`` flag.
+The pragma can take two values: ``on`` and ``off``.
+

Do you want to add an example here?



Comment at: clang/docs/LanguageExtensions.rst:3192
 in cases when the language standard does not make this possible (e.g. across
 statements in C)
 

Oh, and there's a missing period here.



Comment at: clang/include/clang/Basic/LangOptions.h:186
+FPM_Fast
   };
 

mibintc wrote:
> rjmccall wrote:
> > I'm not sure I think this fusion was an improvement; the net effect was to 
> > remove a few lines from this header and make a bunch of switches 
> > unnecessarily non-exhaustive.
> I dropped the on/off enumeration and just using boolean, where needed, to 
> show the setting, do you like this better? 
Yeah, thanks.



Comment at: clang/include/clang/Sema/Sema.h:9624
+  /// \#pragma clang fp reassociate
+  void ActOnPragmaFPAllowReassociation(bool IsEnabled);
 

Please name this the same as the language feature.



Comment at: clang/lib/Parse/ParsePragma.cpp:2900
   return;
 }
 PP.Lex(Tok);

Please make this a single block by making the condition something like `if 
(!FlagValue || (FlagKind == TokFPAnnotValue::Reassociate && FlagValue == 
TokFPAnnotValue::Fast))`.


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D78827



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


[PATCH] D78827: Add support for #pragma clang fp reassociate(on|off) -- floating point control of associative math transformations

2020-05-04 Thread Steve Canon via Phabricator via cfe-commits
scanon added inline comments.



Comment at: clang/docs/LanguageExtensions.rst:3182
+enabled for the translation unit with the ``-fassociative-math`` flag.
+The pragma can take two values: ``on`` and ``off``.
+

rjmccall wrote:
> Do you want to add an example here?
Is the intention that this allows reassociation only within statements (like fp 
contract on)? Based on the ir in the tests, I think the answer is "no".

If so, should "on" be called "fast" instead, since its semantics match the 
"fast" semantics for contract, and reserve "on" for reassociation within a 
statement (that seems like it would also be useful, potentially)?

Otherwise, please add some tests with multiple statements.

I agree with John that `pragma clang fp reassociate` is a reasonable spelling.


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D78827



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


[PATCH] D78827: Add support for #pragma clang fp reassociate(on|off) -- floating point control of associative math transformations

2020-05-04 Thread Melanie Blower via Phabricator via cfe-commits
mibintc updated this revision to Diff 261875.
mibintc retitled this revision from "Add support for #pragma clang fp 
reassoc(on|off) -- floating point control of associative math transformations" 
to "Add support for #pragma clang fp reassociate(on|off) -- floating point 
control of associative math transformations".
mibintc added a comment.

Responded to @rjmccall 's review.


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D78827

Files:
  clang/docs/LanguageExtensions.rst
  clang/include/clang/Basic/DiagnosticParseKinds.td
  clang/include/clang/Basic/LangOptions.def
  clang/include/clang/Basic/LangOptions.h
  clang/include/clang/Sema/Sema.h
  clang/lib/CodeGen/BackendUtil.cpp
  clang/lib/Frontend/CompilerInvocation.cpp
  clang/lib/Parse/ParsePragma.cpp
  clang/lib/Sema/SemaAttr.cpp
  clang/test/CodeGen/fp-reassoc-pragma.cpp
  clang/test/Parser/pragma-fp-contract.c
  clang/test/Parser/pragma-fp.cpp

Index: clang/test/Parser/pragma-fp.cpp
===
--- clang/test/Parser/pragma-fp.cpp
+++ clang/test/Parser/pragma-fp.cpp
@@ -1,14 +1,14 @@
 // RUN: %clang_cc1 -std=c++11 -verify %s
 
 void test_0(int *List, int Length) {
-/* expected-error@+1 {{missing option; expected contract}} */
+/* expected-error@+1 {{missing option; expected 'contract' or 'reassociate'}} */
 #pragma clang fp
   for (int i = 0; i < Length; i++) {
 List[i] = i;
   }
 }
 void test_1(int *List, int Length) {
-/* expected-error@+1 {{invalid option 'blah'; expected contract}} */
+/* expected-error@+1 {{invalid option 'blah'; expected 'contract' or 'reassociate'}} */
 #pragma clang fp blah
   for (int i = 0; i < Length; i++) {
 List[i] = i;
@@ -24,7 +24,7 @@
 }
 
 void test_4(int *List, int Length) {
-/* expected-error@+1 {{unexpected argument 'while' to '#pragma clang fp contract'; expected 'on', 'fast' or 'off'}} */
+/* expected-error@+1 {{unexpected argument 'while' to '#pragma clang fp contract'; expected 'fast' or 'on' or 'off'}} */
 #pragma clang fp contract(while)
   for (int i = 0; i < Length; i++) {
 List[i] = i;
@@ -32,7 +32,7 @@
 }
 
 void test_5(int *List, int Length) {
-/* expected-error@+1 {{unexpected argument 'maybe' to '#pragma clang fp contract'; expected 'on', 'fast' or 'off'}} */
+/* expected-error@+1 {{unexpected argument 'maybe' to '#pragma clang fp contract'; expected 'fast' or 'on' or 'off'}} */
 #pragma clang fp contract(maybe)
   for (int i = 0; i < Length; i++) {
 List[i] = i;
Index: clang/test/Parser/pragma-fp-contract.c
===
--- clang/test/Parser/pragma-fp-contract.c
+++ clang/test/Parser/pragma-fp-contract.c
@@ -23,3 +23,18 @@
 // expected-error@+1 {{this pragma cannot appear in union declaration}}
 #pragma STDC FP_CONTRACT ON
 };
+
+float fp_reassoc_fail(float a, float b) {
+  // CHECK-LABEL: fp_reassoc_fail
+  // expected-error@+2{{'#pragma clang fp' can only appear at file scope or at the start of a compound statement}}
+  float c = a + b;
+#pragma clang fp reassociate(on)
+  return c - b;
+}
+
+float fp_reassoc_no_fast(float a, float b) {
+// CHECK-LABEL: fp_reassoc_no_fast
+// expected-error@+1{{unexpected argument 'fast' to '#pragma clang fp reassociate'; expected 'on' or 'off'}}
+#pragma clang fp reassociate(fast)
+  return a - b;
+}
Index: clang/test/CodeGen/fp-reassoc-pragma.cpp
===
--- /dev/null
+++ clang/test/CodeGen/fp-reassoc-pragma.cpp
@@ -0,0 +1,90 @@
+// RUN: %clang_cc1 -O3 -triple %itanium_abi_triple -emit-llvm -o - %s | FileCheck %s
+// Simple case
+float fp_reassoc_simple(float a, float b, float c) {
+// CHECK: _Z17fp_reassoc_simplefff
+// CHECK: %[[M:.+]] = fmul reassoc float %a, %b
+// CHECK-NEXT: fadd reassoc float %[[M]], %c
+#pragma clang fp reassociate(on)
+  return a * b + c;
+}
+
+// Reassoc pragma should only apply to its scope
+float fp_reassoc_scoped(float a, float b, float c) {
+  // CHECK: _Z17fp_reassoc_scopedfff
+  // CHECK: %[[M:.+]] = fmul float %a, %b
+  // CHECK-NEXT: fadd float %[[M]], %c
+  {
+#pragma clang fp reassociate(on)
+  }
+  return a * b + c;
+}
+
+// Reassoc pragma should apply to templates as well
+class Foo {};
+Foo operator+(Foo, Foo);
+template 
+T template_reassoc(T a, T b, T c) {
+#pragma clang fp reassociate(on)
+  return ((a + b) - c) + c;
+}
+
+float fp_reassoc_template(float a, float b, float c) {
+  // CHECK: _Z19fp_reassoc_templatefff
+  // CHECK: %[[A1:.+]] = fadd reassoc float %a, %b
+  // CHECK-NEXT: %[[A2:.+]] = fsub reassoc float %[[A1]], %c
+  // CHECK-NEXT: fadd reassoc float %[[A2]], %c
+  return template_reassoc(a, b, c);
+}
+
+// File Scoping should work across functions
+#pragma clang fp reassociate(on)
+float fp_file_scope_on(float a, float b, float c) {
+  // CHECK: _Z16fp_file_scope_onfff
+  // CHECK: %[[M1:.+]] = fmul reassoc float %a, %c
+  // CHECK-NEXT: 

[PATCH] D78827: Add support for #pragma clang fp reassociate(on|off) -- floating point control of associative math transformations

2020-05-04 Thread Melanie Blower via Phabricator via cfe-commits
mibintc marked 4 inline comments as done.
mibintc added inline comments.



Comment at: clang/include/clang/Basic/LangOptions.h:186
+FPM_Fast
   };
 

rjmccall wrote:
> I'm not sure I think this fusion was an improvement; the net effect was to 
> remove a few lines from this header and make a bunch of switches 
> unnecessarily non-exhaustive.
I dropped the on/off enumeration and just using boolean, where needed, to show 
the setting, do you like this better? 


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D78827



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