[PATCH] D44931: [WebAssembly] Use Windows EH instructions for Wasm EH

2018-05-19 Thread Heejin Ahn via Phabricator via cfe-commits
aheejin updated this revision to Diff 147696.
aheejin added a comment.

Test case fix was missing in the last commit


Repository:
  rC Clang

https://reviews.llvm.org/D44931

Files:
  lib/CodeGen/CGCXXABI.h
  lib/CodeGen/CGCleanup.cpp
  lib/CodeGen/CGCleanup.h
  lib/CodeGen/CGException.cpp
  lib/CodeGen/CodeGenFunction.h
  lib/CodeGen/ItaniumCXXABI.cpp
  lib/CodeGen/MicrosoftCXXABI.cpp
  test/CodeGenCXX/wasm-eh.cpp

Index: test/CodeGenCXX/wasm-eh.cpp
===
--- /dev/null
+++ test/CodeGenCXX/wasm-eh.cpp
@@ -0,0 +1,384 @@
+// RUN: %clang_cc1 %s -triple wasm32-unknown-unknown -fms-extensions -fexceptions -fcxx-exceptions -emit-llvm -o - -std=c++11 | FileCheck %s
+// RUN: %clang_cc1 %s -triple wasm64-unknown-unknown -fms-extensions -fexceptions -fcxx-exceptions -emit-llvm -o - -std=c++11 | FileCheck %s
+
+void may_throw();
+void dont_throw() noexcept;
+
+struct Cleanup {
+  ~Cleanup() { dont_throw(); }
+};
+
+// Multiple catch clauses w/o catch-all
+void test0() {
+  try {
+may_throw();
+  } catch (int) {
+dont_throw();
+  } catch (double) {
+dont_throw();
+  }
+}
+
+// CHECK-LABEL: define void @_Z5test0v() {{.*}} personality i8* bitcast (i32 (...)* @__gxx_wasm_personality_v0 to i8*)
+
+// CHECK:   %[[INT_ALLOCA:.*]] = alloca i32
+// CHECK:   invoke void @_Z9may_throwv()
+// CHECK-NEXT:   to label %[[NORMAL_BB:.*]] unwind label %[[CATCHDISPATCH_BB:.*]]
+
+// CHECK: [[CATCHDISPATCH_BB]]:
+// CHECK-NEXT:   %[[CATCHSWITCH:.*]] = catchswitch within none [label %[[CATCHSTART_BB:.*]]] unwind to caller
+
+// CHECK: [[CATCHSTART_BB]]:
+// CHECK-NEXT:   %[[CATCHPAD:.*]] = catchpad within %[[CATCHSWITCH]] [i8* bitcast (i8** @_ZTIi to i8*), i8* bitcast (i8** @_ZTId to i8*)]
+// CHECK-NEXT:   %[[EXN:.*]] = call i8* @llvm.wasm.get.exception(token %[[CATCHPAD]])
+// CHECK-NEXT:   store i8* %[[EXN]], i8** %exn.slot
+// CHECK-NEXT:   %[[SELECTOR:.*]] = call i32 @llvm.wasm.get.ehselector(token %[[CATCHPAD]])
+// CHECK-NEXT:   %[[TYPEID:.*]] = call i32 @llvm.eh.typeid.for(i8* bitcast (i8** @_ZTIi to i8*)) #2
+// CHECK-NEXT:   %[[MATCHES:.*]] = icmp eq i32 %[[SELECTOR]], %[[TYPEID]]
+// CHECK-NEXT:   br i1 %[[MATCHES]], label %[[CATCH_INT_BB:.*]], label %[[CATCH_FALLTHROUGH_BB:.*]]
+
+// CHECK: [[CATCH_INT_BB]]:
+// CHECK-NEXT:   %[[EXN:.*]] = load i8*, i8** %exn.slot
+// CHECK-NEXT:   %[[ADDR:.*]] = call i8* @__cxa_begin_catch(i8* %[[EXN]]) {{.*}} [ "funclet"(token %[[CATCHPAD]]) ]
+// CHECK-NEXT:   %[[ADDR_CAST:.*]] = bitcast i8* %[[ADDR]] to i32*
+// CHECK-NEXT:   %[[INT_VAL:.*]] = load i32, i32* %[[ADDR_CAST]]
+// CHECK-NEXT:   store i32 %[[INT_VAL]], i32* %[[INT_ALLOCA]]
+// CHECK-NEXT:   call void @_Z10dont_throwv() {{.*}} [ "funclet"(token %[[CATCHPAD]]) ]
+// CHECK-NEXT:   call void @__cxa_end_catch() {{.*}} [ "funclet"(token %[[CATCHPAD]]) ]
+// CHECK-NEXT:   catchret from %[[CATCHPAD]] to label %[[CATCHRET_DEST_BB0:.*]]
+
+// CHECK: [[CATCHRET_DEST_BB0]]:
+// CHECK-NEXT:   br label %[[TRY_CONT_BB:.*]]
+
+// CHECK: [[CATCH_FALLTHROUGH_BB]]
+// CHECK-NEXT:   %[[TYPEID:.*]] = call i32 @llvm.eh.typeid.for(i8* bitcast (i8** @_ZTId to i8*)) #2
+// CHECK-NEXT:   %[[MATCHES:.*]] = icmp eq i32 %[[SELECTOR]], %[[TYPEID]]
+// CHECK-NEXT:   br i1 %[[MATCHES]], label %[[CATCH_FLOAT_BB:.*]], label %[[RETHROW_BB:.*]]
+
+// CHECK: [[CATCH_FLOAT_BB]]:
+// CHECK:   catchret from %[[CATCHPAD]] to label %[[CATCHRET_DEST_BB1:.*]]
+
+// CHECK: [[CATCHRET_DEST_BB1]]:
+// CHECK-NEXT:   br label %[[TRY_CONT_BB]]
+
+// CHECK: [[RETHROW_BB]]:
+// CHECK-NEXT:   call void @__cxa_rethrow() {{.*}} [ "funclet"(token %[[CATCHPAD]]) ]
+// CHECK-NEXT:   unreachable
+
+// Single catch-all
+void test1() {
+  try {
+may_throw();
+  } catch (...) {
+dont_throw();
+  }
+}
+
+// CATCH-LABEL: @_Z5test1v()
+
+// CHECK:   %[[CATCHSWITCH:.*]] = catchswitch within none [label %[[CATCHSTART_BB:.*]]] unwind to caller
+
+// CHECK: [[CATCHSTART_BB]]:
+// CHECK-NEXT:   %[[CATCHPAD:.*]] = catchpad within %[[CATCHSWITCH]] [i8* null]
+// CHECK:   br label %[[CATCH_ALL_BB:.*]]
+
+// CHECK: [[CATCH_ALL_BB]]:
+// CHECK:   catchret from %[[CATCHPAD]] to label
+
+// Multiple catch clauses w/ catch-all
+void test2() {
+  try {
+may_throw();
+  } catch (int) {
+dont_throw();
+  } catch (...) {
+dont_throw();
+  }
+}
+
+// CHECK-LABEL: @_Z5test2v()
+
+// CHECK:   %[[CATCHSWITCH:.*]] = catchswitch within none [label %[[CATCHSTART_BB:.*]]] unwind to caller
+
+// CHECK: [[CATCHSTART_BB]]:
+// CHECK-NEXT:   %[[CATCHPAD:.*]] = catchpad within %[[CATCHSWITCH]] [i8* bitcast (i8** @_ZTIi to i8*), i8* null]
+// CHECK:   br i1 %{{.*}}, label %[[CATCH_INT_BB:.*]], label %[[CATCH_ALL_BB:.*]]
+
+// CHECK: [[CATCH_INT_BB]]:
+// CHECK:   catchret from %[[CATCHPAD]] to label
+
+// CHECK: [[CATCH_ALL_BB]]:
+// CHECK:   catchret from %[[CATCHPAD]] to label
+
+// Cleanup
+void test3() {
+  Cleanup c;
+  may_throw();
+}
+
+// CHECK-LABEL: @_Z5test3v()
+
+// CHECK:   invoke void @_Z9may_throwv()
+// 

[PATCH] D44931: [WebAssembly] Use Windows EH instructions for Wasm EH

2018-05-19 Thread Heejin Ahn via Phabricator via cfe-commits
aheejin updated this revision to Diff 147695.
aheejin added a comment.

- Make `wasm.get.exception/selector` intrinsics take a token argument


Repository:
  rC Clang

https://reviews.llvm.org/D44931

Files:
  lib/CodeGen/CGCXXABI.h
  lib/CodeGen/CGCleanup.cpp
  lib/CodeGen/CGCleanup.h
  lib/CodeGen/CGException.cpp
  lib/CodeGen/CodeGenFunction.h
  lib/CodeGen/ItaniumCXXABI.cpp
  lib/CodeGen/MicrosoftCXXABI.cpp
  test/CodeGenCXX/wasm-eh.cpp

Index: test/CodeGenCXX/wasm-eh.cpp
===
--- /dev/null
+++ test/CodeGenCXX/wasm-eh.cpp
@@ -0,0 +1,384 @@
+// RUN: %clang_cc1 %s -triple wasm32-unknown-unknown -fms-extensions -fexceptions -fcxx-exceptions -emit-llvm -o - -std=c++11 | FileCheck %s
+// RUN: %clang_cc1 %s -triple wasm64-unknown-unknown -fms-extensions -fexceptions -fcxx-exceptions -emit-llvm -o - -std=c++11 | FileCheck %s
+
+void may_throw();
+void dont_throw() noexcept;
+
+struct Cleanup {
+  ~Cleanup() { dont_throw(); }
+};
+
+// Multiple catch clauses w/o catch-all
+void test0() {
+  try {
+may_throw();
+  } catch (int) {
+dont_throw();
+  } catch (double) {
+dont_throw();
+  }
+}
+
+// CHECK-LABEL: define void @_Z5test0v() {{.*}} personality i8* bitcast (i32 (...)* @__gxx_wasm_personality_v0 to i8*)
+
+// CHECK:   %[[INT_ALLOCA:.*]] = alloca i32
+// CHECK:   invoke void @_Z9may_throwv()
+// CHECK-NEXT:   to label %[[NORMAL_BB:.*]] unwind label %[[CATCHDISPATCH_BB:.*]]
+
+// CHECK: [[CATCHDISPATCH_BB]]:
+// CHECK-NEXT:   %[[CATCHSWITCH:.*]] = catchswitch within none [label %[[CATCHSTART_BB:.*]]] unwind to caller
+
+// CHECK: [[CATCHSTART_BB]]:
+// CHECK-NEXT:   %[[CATCHPAD:.*]] = catchpad within %[[CATCHSWITCH]] [i8* bitcast (i8** @_ZTIi to i8*), i8* bitcast (i8** @_ZTId to i8*)]
+// CHECK-NEXT:   %[[EXN:.*]] = call i8* @llvm.wasm.get.exception()
+// CHECK-NEXT:   store i8* %[[EXN]], i8** %exn.slot
+// CHECK-NEXT:   %[[SELECTOR:.*]] = call i32 @llvm.wasm.get.ehselector()
+// CHECK-NEXT:   %[[TYPEID:.*]] = call i32 @llvm.eh.typeid.for(i8* bitcast (i8** @_ZTIi to i8*)) #2
+// CHECK-NEXT:   %[[MATCHES:.*]] = icmp eq i32 %[[SELECTOR]], %[[TYPEID]]
+// CHECK-NEXT:   br i1 %[[MATCHES]], label %[[CATCH_INT_BB:.*]], label %[[CATCH_FALLTHROUGH_BB:.*]]
+
+// CHECK: [[CATCH_INT_BB]]:
+// CHECK-NEXT:   %[[EXN:.*]] = load i8*, i8** %exn.slot
+// CHECK-NEXT:   %[[ADDR:.*]] = call i8* @__cxa_begin_catch(i8* %[[EXN]]) {{.*}} [ "funclet"(token %[[CATCHPAD]]) ]
+// CHECK-NEXT:   %[[ADDR_CAST:.*]] = bitcast i8* %[[ADDR]] to i32*
+// CHECK-NEXT:   %[[INT_VAL:.*]] = load i32, i32* %[[ADDR_CAST]]
+// CHECK-NEXT:   store i32 %[[INT_VAL]], i32* %[[INT_ALLOCA]]
+// CHECK-NEXT:   call void @_Z10dont_throwv() {{.*}} [ "funclet"(token %[[CATCHPAD]]) ]
+// CHECK-NEXT:   call void @__cxa_end_catch() {{.*}} [ "funclet"(token %[[CATCHPAD]]) ]
+// CHECK-NEXT:   catchret from %[[CATCHPAD]] to label %[[CATCHRET_DEST_BB0:.*]]
+
+// CHECK: [[CATCHRET_DEST_BB0]]:
+// CHECK-NEXT:   br label %[[TRY_CONT_BB:.*]]
+
+// CHECK: [[CATCH_FALLTHROUGH_BB]]
+// CHECK-NEXT:   %[[TYPEID:.*]] = call i32 @llvm.eh.typeid.for(i8* bitcast (i8** @_ZTId to i8*)) #2
+// CHECK-NEXT:   %[[MATCHES:.*]] = icmp eq i32 %[[SELECTOR]], %[[TYPEID]]
+// CHECK-NEXT:   br i1 %[[MATCHES]], label %[[CATCH_FLOAT_BB:.*]], label %[[RETHROW_BB:.*]]
+
+// CHECK: [[CATCH_FLOAT_BB]]:
+// CHECK:   catchret from %[[CATCHPAD]] to label %[[CATCHRET_DEST_BB1:.*]]
+
+// CHECK: [[CATCHRET_DEST_BB1]]:
+// CHECK-NEXT:   br label %[[TRY_CONT_BB]]
+
+// CHECK: [[RETHROW_BB]]:
+// CHECK-NEXT:   call void @__cxa_rethrow() {{.*}} [ "funclet"(token %[[CATCHPAD]]) ]
+// CHECK-NEXT:   unreachable
+
+// Single catch-all
+void test1() {
+  try {
+may_throw();
+  } catch (...) {
+dont_throw();
+  }
+}
+
+// CATCH-LABEL: @_Z5test1v()
+
+// CHECK:   %[[CATCHSWITCH:.*]] = catchswitch within none [label %[[CATCHSTART_BB:.*]]] unwind to caller
+
+// CHECK: [[CATCHSTART_BB]]:
+// CHECK-NEXT:   %[[CATCHPAD:.*]] = catchpad within %[[CATCHSWITCH]] [i8* null]
+// CHECK:   br label %[[CATCH_ALL_BB:.*]]
+
+// CHECK: [[CATCH_ALL_BB]]:
+// CHECK:   catchret from %[[CATCHPAD]] to label
+
+// Multiple catch clauses w/ catch-all
+void test2() {
+  try {
+may_throw();
+  } catch (int) {
+dont_throw();
+  } catch (...) {
+dont_throw();
+  }
+}
+
+// CHECK-LABEL: @_Z5test2v()
+
+// CHECK:   %[[CATCHSWITCH:.*]] = catchswitch within none [label %[[CATCHSTART_BB:.*]]] unwind to caller
+
+// CHECK: [[CATCHSTART_BB]]:
+// CHECK-NEXT:   %[[CATCHPAD:.*]] = catchpad within %[[CATCHSWITCH]] [i8* bitcast (i8** @_ZTIi to i8*), i8* null]
+// CHECK:   br i1 %{{.*}}, label %[[CATCH_INT_BB:.*]], label %[[CATCH_ALL_BB:.*]]
+
+// CHECK: [[CATCH_INT_BB]]:
+// CHECK:   catchret from %[[CATCHPAD]] to label
+
+// CHECK: [[CATCH_ALL_BB]]:
+// CHECK:   catchret from %[[CATCHPAD]] to label
+
+// Cleanup
+void test3() {
+  Cleanup c;
+  may_throw();
+}
+
+// CHECK-LABEL: @_Z5test3v()
+
+// CHECK:   invoke void @_Z9may_throwv()
+// CHECK-NEXT:  

[PATCH] D47103: Implement strip.invariant.group

2018-05-19 Thread Piotr Padlewski via Phabricator via cfe-commits
Prazek updated this revision to Diff 147691.
Prazek added a comment.

rebase


Repository:
  rL LLVM

https://reviews.llvm.org/D47103

Files:
  clang/include/clang/AST/DeclCXX.h
  clang/lib/CodeGen/CGExpr.cpp
  clang/lib/CodeGen/CGExprScalar.cpp
  clang/test/CodeGenCXX/strict-vtable-pointers.cpp
  llvm/docs/LangRef.rst
  llvm/include/llvm/IR/IRBuilder.h
  llvm/include/llvm/IR/Intrinsics.td
  llvm/lib/Analysis/BasicAliasAnalysis.cpp
  llvm/lib/Analysis/ConstantFolding.cpp
  llvm/lib/Analysis/ValueTracking.cpp
  llvm/lib/CodeGen/CodeGenPrepare.cpp
  llvm/lib/CodeGen/SelectionDAG/FastISel.cpp
  llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp
  llvm/lib/IR/Value.cpp
  llvm/lib/Target/AMDGPU/AMDGPUPromoteAlloca.cpp
  llvm/test/Analysis/ValueTracking/invariant.group.ll
  llvm/test/CodeGen/Generic/intrinsics.ll
  llvm/test/Other/invariant.group.ll
  llvm/test/Other/launder.invariant.group.ll
  llvm/test/Transforms/CodeGenPrepare/invariant.group.ll
  llvm/test/Transforms/DeadStoreElimination/launder.invariant.group.ll
  llvm/test/Transforms/FunctionAttrs/nocapture.ll
  llvm/test/Transforms/GVN/invariant.group.ll
  llvm/test/Transforms/GlobalOpt/invariant.group.barrier.ll
  llvm/test/Transforms/GlobalOpt/invariant.group.ll
  llvm/test/Transforms/InstCombine/invariant.group.ll
  llvm/test/Transforms/NewGVN/invariant.group.ll

Index: llvm/test/Transforms/NewGVN/invariant.group.ll
===
--- llvm/test/Transforms/NewGVN/invariant.group.ll
+++ llvm/test/Transforms/NewGVN/invariant.group.ll
@@ -52,6 +52,19 @@
 ret i8 %b
 }
 
+; CHECK-LABEL: define i1 @proveEqualityForStrip(
+define i1 @proveEqualityForStrip(i8* %a) {
+; FIXME: The first call could be also removed by GVN. Right now
+; DCE removes it. The second call is CSE'd with the first one.
+; CHECK: %b1 = call i8* @llvm.strip.invariant.group.p0i8(i8* %a)
+  %b1 = call i8* @llvm.strip.invariant.group.p0i8(i8* %a)
+; CHECK-NOT: llvm.strip.invariant.group
+  %b2 = call i8* @llvm.strip.invariant.group.p0i8(i8* %a)
+  %r = icmp eq i8* %b1, %b2
+; CHECK: ret i1 true
+  ret i1 %r
+}
+
 ; CHECK-LABEL: define i8 @unoptimizable1() {
 define i8 @unoptimizable1() {
 entry:
Index: llvm/test/Transforms/InstCombine/invariant.group.ll
===
--- llvm/test/Transforms/InstCombine/invariant.group.ll
+++ llvm/test/Transforms/InstCombine/invariant.group.ll
@@ -1,5 +1,6 @@
 ; RUN: opt -instcombine -S < %s | FileCheck %s
 
+
 ; CHECK-LABEL: define i8* @simplifyNullLaunder()
 define i8* @simplifyNullLaunder() {
 ; CHECK-NEXT: ret i8* null
@@ -29,6 +30,39 @@
   ret i8 addrspace(42)* %b2
 }
 
-
 declare i8* @llvm.launder.invariant.group.p0i8(i8*)
 declare i8 addrspace(42)* @llvm.launder.invariant.group.p42i8(i8 addrspace(42)*)
+
+
+; CHECK-LABEL: define i8* @simplifyNullStrip()
+define i8* @simplifyNullStrip() {
+; CHECK-NEXT: ret i8* null
+  %b2 = call i8* @llvm.strip.invariant.group.p0i8(i8* null)
+  ret i8* %b2
+}
+
+; CHECK-LABEL: define i8 addrspace(42)* @dontsimplifyNullStripForDifferentAddrspace()
+define i8 addrspace(42)* @dontsimplifyNullStripForDifferentAddrspace() {
+; CHECK: %b2 = call i8 addrspace(42)* @llvm.strip.invariant.group.p42i8(i8 addrspace(42)* null)
+; CHECK: ret i8 addrspace(42)* %b2
+  %b2 = call i8 addrspace(42)* @llvm.strip.invariant.group.p42i8(i8 addrspace(42)* null)
+  ret i8 addrspace(42)* %b2
+}
+
+; CHECK-LABEL: define i8* @simplifyUndefStrip()
+define i8* @simplifyUndefStrip() {
+; CHECK-NEXT: ret i8* undef
+  %b2 = call i8* @llvm.strip.invariant.group.p0i8(i8* undef)
+  ret i8* %b2
+}
+
+; CHECK-LABEL: define i8 addrspace(42)* @simplifyUndefStrip2()
+define i8 addrspace(42)* @simplifyUndefStrip2() {
+; CHECK-NEXT: ret i8 addrspace(42)* undef
+  %b2 = call i8 addrspace(42)* @llvm.strip.invariant.group.p42i8(i8 addrspace(42)* undef)
+  ret i8 addrspace(42)* %b2
+}
+
+declare i8* @llvm.strip.invariant.group.p0i8(i8*)
+declare i8 addrspace(42)* @llvm.strip.invariant.group.p42i8(i8 addrspace(42)*)
+
Index: llvm/test/Transforms/GlobalOpt/invariant.group.ll
===
--- llvm/test/Transforms/GlobalOpt/invariant.group.ll
+++ llvm/test/Transforms/GlobalOpt/invariant.group.ll
@@ -27,46 +27,46 @@
 define void @_optimizable() {
 enter:
   %valptr = alloca i32
-  
+
   %val = call i32 @TheAnswerToLifeTheUniverseAndEverything()
   store i32 %val, i32* @tmp
   store i32 %val, i32* %valptr
-  
+
   %0 = bitcast i32* %valptr to i8*
   %barr = call i8* @llvm.launder.invariant.group(i8* %0)
   %1 = bitcast i8* %barr to i32*
-  
+
   %val2 = load i32, i32* %1
   store i32 %val2, i32* @tmp2
   ret void
 }
 
 ; We can't step through launder.invariant.group here, because that would change
 ; this load in @usage_of_globals()
-; val = load i32, i32* %ptrVal, !invariant.group !0 
-; into 
+; val = load i32, i32* %ptrVal, !invariant.group !0
+; into
 ; %val = load i32, i32* @tmp3, !invariant.group 

[PATCH] D47103: Implement strip.invariant.group

2018-05-19 Thread Piotr Padlewski via Phabricator via cfe-commits
Prazek updated this revision to Diff 147688.
Prazek added a comment.

After rebasing


Repository:
  rL LLVM

https://reviews.llvm.org/D47103

Files:
  clang/include/clang/AST/DeclCXX.h
  clang/lib/CodeGen/CGExpr.cpp
  clang/lib/CodeGen/CGExprScalar.cpp
  clang/test/CodeGenCXX/strict-vtable-pointers.cpp
  llvm/docs/LangRef.rst
  llvm/include/llvm/IR/IRBuilder.h
  llvm/include/llvm/IR/Intrinsics.td
  llvm/lib/Analysis/BasicAliasAnalysis.cpp
  llvm/lib/Analysis/ConstantFolding.cpp
  llvm/lib/Analysis/ValueTracking.cpp
  llvm/lib/CodeGen/CodeGenPrepare.cpp
  llvm/lib/CodeGen/SelectionDAG/FastISel.cpp
  llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp
  llvm/lib/IR/Value.cpp
  llvm/lib/Target/AMDGPU/AMDGPUPromoteAlloca.cpp
  llvm/test/Analysis/ValueTracking/invariant.group.ll
  llvm/test/CodeGen/Generic/intrinsics.ll
  llvm/test/Other/invariant.group.ll
  llvm/test/Other/launder.invariant.group.ll
  llvm/test/Transforms/CodeGenPrepare/invariant.group.ll
  llvm/test/Transforms/DeadStoreElimination/launder.invariant.group.ll
  llvm/test/Transforms/FunctionAttrs/nocapture.ll
  llvm/test/Transforms/GVN/invariant.group.ll
  llvm/test/Transforms/GlobalOpt/invariant.group.barrier.ll
  llvm/test/Transforms/GlobalOpt/invariant.group.ll
  llvm/test/Transforms/InstCombine/invariant.group.ll
  llvm/test/Transforms/NewGVN/invariant.group.ll

Index: llvm/test/Transforms/NewGVN/invariant.group.ll
===
--- llvm/test/Transforms/NewGVN/invariant.group.ll
+++ llvm/test/Transforms/NewGVN/invariant.group.ll
@@ -52,6 +52,19 @@
 ret i8 %b
 }
 
+; CHECK-LABEL: define i1 @proveEqualityForStrip(
+define i1 @proveEqualityForStrip(i8* %a) {
+; FIXME: The first call could be also removed by GVN. Right now
+; DCE removes it. The second call is CSE'd with the first one.
+; CHECK: %b1 = call i8* @llvm.strip.invariant.group.p0i8(i8* %a)
+  %b1 = call i8* @llvm.strip.invariant.group.p0i8(i8* %a)
+; CHECK-NOT: llvm.strip.invariant.group
+  %b2 = call i8* @llvm.strip.invariant.group.p0i8(i8* %a)
+  %r = icmp eq i8* %b1, %b2
+; CHECK: ret i1 true
+  ret i1 %r
+}
+
 ; CHECK-LABEL: define i8 @unoptimizable1() {
 define i8 @unoptimizable1() {
 entry:
Index: llvm/test/Transforms/InstCombine/invariant.group.ll
===
--- llvm/test/Transforms/InstCombine/invariant.group.ll
+++ llvm/test/Transforms/InstCombine/invariant.group.ll
@@ -1,5 +1,6 @@
 ; RUN: opt -instcombine -S < %s | FileCheck %s
 
+
 ; CHECK-LABEL: define i8* @simplifyNullLaunder()
 define i8* @simplifyNullLaunder() {
 ; CHECK-NEXT: ret i8* null
@@ -29,6 +30,39 @@
   ret i8 addrspace(42)* %b2
 }
 
-
 declare i8* @llvm.launder.invariant.group.p0i8(i8*)
 declare i8 addrspace(42)* @llvm.launder.invariant.group.p42i8(i8 addrspace(42)*)
+
+
+; CHECK-LABEL: define i8* @simplifyNullStrip()
+define i8* @simplifyNullStrip() {
+; CHECK-NEXT: ret i8* null
+  %b2 = call i8* @llvm.strip.invariant.group.p0i8(i8* null)
+  ret i8* %b2
+}
+
+; CHECK-LABEL: define i8 addrspace(42)* @dontsimplifyNullStripForDifferentAddrspace()
+define i8 addrspace(42)* @dontsimplifyNullStripForDifferentAddrspace() {
+; CHECK: %b2 = call i8 addrspace(42)* @llvm.strip.invariant.group.p42i8(i8 addrspace(42)* null)
+; CHECK: ret i8 addrspace(42)* %b2
+  %b2 = call i8 addrspace(42)* @llvm.strip.invariant.group.p42i8(i8 addrspace(42)* null)
+  ret i8 addrspace(42)* %b2
+}
+
+; CHECK-LABEL: define i8* @simplifyUndefStrip()
+define i8* @simplifyUndefStrip() {
+; CHECK-NEXT: ret i8* undef
+  %b2 = call i8* @llvm.strip.invariant.group.p0i8(i8* undef)
+  ret i8* %b2
+}
+
+; CHECK-LABEL: define i8 addrspace(42)* @simplifyUndefStrip2()
+define i8 addrspace(42)* @simplifyUndefStrip2() {
+; CHECK-NEXT: ret i8 addrspace(42)* undef
+  %b2 = call i8 addrspace(42)* @llvm.strip.invariant.group.p42i8(i8 addrspace(42)* undef)
+  ret i8 addrspace(42)* %b2
+}
+
+declare i8* @llvm.strip.invariant.group.p0i8(i8*)
+declare i8 addrspace(42)* @llvm.strip.invariant.group.p42i8(i8 addrspace(42)*)
+
Index: llvm/test/Transforms/GlobalOpt/invariant.group.ll
===
--- llvm/test/Transforms/GlobalOpt/invariant.group.ll
+++ llvm/test/Transforms/GlobalOpt/invariant.group.ll
@@ -27,46 +27,46 @@
 define void @_optimizable() {
 enter:
   %valptr = alloca i32
-  
+
   %val = call i32 @TheAnswerToLifeTheUniverseAndEverything()
   store i32 %val, i32* @tmp
   store i32 %val, i32* %valptr
-  
+
   %0 = bitcast i32* %valptr to i8*
   %barr = call i8* @llvm.launder.invariant.group(i8* %0)
   %1 = bitcast i8* %barr to i32*
-  
+
   %val2 = load i32, i32* %1
   store i32 %val2, i32* @tmp2
   ret void
 }
 
 ; We can't step through launder.invariant.group here, because that would change
 ; this load in @usage_of_globals()
-; val = load i32, i32* %ptrVal, !invariant.group !0 
-; into 
+; val = load i32, i32* %ptrVal, !invariant.group !0
+; into
 ; %val = load i32, i32* @tmp3, 

[PATCH] D47103: Implement strip.invariant.group

2018-05-19 Thread Piotr Padlewski via Phabricator via cfe-commits
Prazek updated this revision to Diff 147684.
Prazek added a comment.

Changed comments


Repository:
  rL LLVM

https://reviews.llvm.org/D47103

Files:
  clang/include/clang/AST/DeclCXX.h
  clang/lib/CodeGen/CGExpr.cpp
  clang/lib/CodeGen/CGExprScalar.cpp
  clang/test/CodeGenCXX/strict-vtable-pointers.cpp
  llvm/docs/LangRef.rst
  llvm/include/llvm/IR/IRBuilder.h
  llvm/include/llvm/IR/Intrinsics.td
  llvm/lib/Analysis/BasicAliasAnalysis.cpp
  llvm/lib/Analysis/CaptureTracking.cpp
  llvm/lib/Analysis/ConstantFolding.cpp
  llvm/lib/Analysis/ValueTracking.cpp
  llvm/lib/CodeGen/CodeGenPrepare.cpp
  llvm/lib/CodeGen/SelectionDAG/FastISel.cpp
  llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp
  llvm/lib/IR/Value.cpp
  llvm/lib/Target/AMDGPU/AMDGPUPromoteAlloca.cpp
  llvm/test/Analysis/ValueTracking/invariant.group.ll
  llvm/test/CodeGen/Generic/intrinsics.ll
  llvm/test/Other/invariant.group.ll
  llvm/test/Other/launder.invariant.group.ll
  llvm/test/Transforms/CodeGenPrepare/invariant.group.ll
  llvm/test/Transforms/DeadStoreElimination/launder.invariant.group.ll
  llvm/test/Transforms/FunctionAttrs/nocapture.ll
  llvm/test/Transforms/GVN/invariant.group.ll
  llvm/test/Transforms/GlobalOpt/invariant.group.barrier.ll
  llvm/test/Transforms/GlobalOpt/invariant.group.ll
  llvm/test/Transforms/InstCombine/invariant.group.ll
  llvm/test/Transforms/NewGVN/invariant.group.ll

Index: llvm/test/Transforms/NewGVN/invariant.group.ll
===
--- llvm/test/Transforms/NewGVN/invariant.group.ll
+++ llvm/test/Transforms/NewGVN/invariant.group.ll
@@ -52,6 +52,19 @@
 ret i8 %b
 }
 
+; CHECK-LABEL: define i1 @proveEqualityForStrip(
+define i1 @proveEqualityForStrip(i8* %a) {
+; FIXME: The first call could be also removed by GVN. Right now
+; DCE removes it. The second call is CSE'd with the first one.
+; CHECK: %b1 = call i8* @llvm.strip.invariant.group.p0i8(i8* %a)
+  %b1 = call i8* @llvm.strip.invariant.group.p0i8(i8* %a)
+; CHECK-NOT: llvm.strip.invariant.group
+  %b2 = call i8* @llvm.strip.invariant.group.p0i8(i8* %a)
+  %r = icmp eq i8* %b1, %b2
+; CHECK: ret i1 true
+  ret i1 %r
+}
+
 ; CHECK-LABEL: define i8 @unoptimizable1() {
 define i8 @unoptimizable1() {
 entry:
Index: llvm/test/Transforms/InstCombine/invariant.group.ll
===
--- llvm/test/Transforms/InstCombine/invariant.group.ll
+++ llvm/test/Transforms/InstCombine/invariant.group.ll
@@ -1,5 +1,6 @@
 ; RUN: opt -instcombine -S < %s | FileCheck %s
 
+
 ; CHECK-LABEL: define i8* @simplifyNullLaunder()
 define i8* @simplifyNullLaunder() {
 ; CHECK-NEXT: ret i8* null
@@ -29,6 +30,39 @@
   ret i8 addrspace(42)* %b2
 }
 
-
 declare i8* @llvm.launder.invariant.group.p0i8(i8*)
 declare i8 addrspace(42)* @llvm.launder.invariant.group.p42i8(i8 addrspace(42)*)
+
+
+; CHECK-LABEL: define i8* @simplifyNullStrip()
+define i8* @simplifyNullStrip() {
+; CHECK-NEXT: ret i8* null
+  %b2 = call i8* @llvm.strip.invariant.group.p0i8(i8* null)
+  ret i8* %b2
+}
+
+; CHECK-LABEL: define i8 addrspace(42)* @dontsimplifyNullStripForDifferentAddrspace()
+define i8 addrspace(42)* @dontsimplifyNullStripForDifferentAddrspace() {
+; CHECK: %b2 = call i8 addrspace(42)* @llvm.strip.invariant.group.p42i8(i8 addrspace(42)* null)
+; CHECK: ret i8 addrspace(42)* %b2
+  %b2 = call i8 addrspace(42)* @llvm.strip.invariant.group.p42i8(i8 addrspace(42)* null)
+  ret i8 addrspace(42)* %b2
+}
+
+; CHECK-LABEL: define i8* @simplifyUndefStrip()
+define i8* @simplifyUndefStrip() {
+; CHECK-NEXT: ret i8* undef
+  %b2 = call i8* @llvm.strip.invariant.group.p0i8(i8* undef)
+  ret i8* %b2
+}
+
+; CHECK-LABEL: define i8 addrspace(42)* @simplifyUndefStrip2()
+define i8 addrspace(42)* @simplifyUndefStrip2() {
+; CHECK-NEXT: ret i8 addrspace(42)* undef
+  %b2 = call i8 addrspace(42)* @llvm.strip.invariant.group.p42i8(i8 addrspace(42)* undef)
+  ret i8 addrspace(42)* %b2
+}
+
+declare i8* @llvm.strip.invariant.group.p0i8(i8*)
+declare i8 addrspace(42)* @llvm.strip.invariant.group.p42i8(i8 addrspace(42)*)
+
Index: llvm/test/Transforms/GlobalOpt/invariant.group.ll
===
--- llvm/test/Transforms/GlobalOpt/invariant.group.ll
+++ llvm/test/Transforms/GlobalOpt/invariant.group.ll
@@ -27,46 +27,46 @@
 define void @_optimizable() {
 enter:
   %valptr = alloca i32
-  
+
   %val = call i32 @TheAnswerToLifeTheUniverseAndEverything()
   store i32 %val, i32* @tmp
   store i32 %val, i32* %valptr
-  
+
   %0 = bitcast i32* %valptr to i8*
   %barr = call i8* @llvm.launder.invariant.group(i8* %0)
   %1 = bitcast i8* %barr to i32*
-  
+
   %val2 = load i32, i32* %1
   store i32 %val2, i32* @tmp2
   ret void
 }
 
 ; We can't step through launder.invariant.group here, because that would change
 ; this load in @usage_of_globals()
-; val = load i32, i32* %ptrVal, !invariant.group !0 
-; into 
+; val = load i32, i32* %ptrVal, !invariant.group !0
+; 

[PATCH] D47111: Implement monotonic_buffer_resource in

2018-05-19 Thread Arthur O'Dwyer via Phabricator via cfe-commits
Quuxplusone created this revision.
Quuxplusone added a reviewer: EricWF.
Herald added a subscriber: cfe-commits.

(https://reviews.llvm.org/D47090 included this in ``; at 
Eric's request, I've split this out into its own patch applied to the existing 
`` instead.)


Repository:
  rCXX libc++

https://reviews.llvm.org/D47111

Files:
  include/experimental/memory_resource
  src/experimental/memory_resource.cpp
  
test/std/experimental/memory/memory.resource.monotonic.buffer/monotonic_buffer.pass.cpp

Index: test/std/experimental/memory/memory.resource.monotonic.buffer/monotonic_buffer.pass.cpp
===
--- /dev/null
+++ test/std/experimental/memory/memory.resource.monotonic.buffer/monotonic_buffer.pass.cpp
@@ -0,0 +1,408 @@
+//===--===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===--===//
+
+// UNSUPPORTED: c++98, c++03
+
+// 
+
+// class monotonic_buffer_resource
+
+#include 
+#include 
+#include 
+#include 
+
+#include "count_new.hpp"
+
+struct assert_on_compare : public std::experimental::pmr::memory_resource
+{
+protected:
+virtual void * do_allocate(size_t, size_t)
+{ assert(false); }
+
+virtual void do_deallocate(void *, size_t, size_t)
+{ assert(false); }
+
+virtual bool do_is_equal(std::experimental::pmr::memory_resource const &) const noexcept
+{ assert(false); }
+};
+
+struct repointable_resource : public std::experimental::pmr::memory_resource
+{
+std::experimental::pmr::memory_resource *which;
+
+explicit repointable_resource(std::experimental::pmr::memory_resource *res) : which(res) {}
+
+protected:
+virtual void *do_allocate(size_t size, size_t align)
+{ return which->allocate(size, align); }
+
+virtual void do_deallocate(void *p, size_t size, size_t align)
+{ return which->deallocate(p, size, align); }
+
+virtual bool do_is_equal(std::experimental::pmr::memory_resource const ) const noexcept
+{ return which->is_equal(rhs); }
+};
+
+void test_construction_with_default_resource()
+{
+std::experimental::pmr::memory_resource *expected = std::experimental::pmr::null_memory_resource();
+std::experimental::pmr::set_default_resource(expected);
+{
+char buffer[16];
+std::experimental::pmr::monotonic_buffer_resource r1;
+std::experimental::pmr::monotonic_buffer_resource r2(16);
+std::experimental::pmr::monotonic_buffer_resource r3(buffer, sizeof buffer);
+assert(r1.upstream_resource() == expected);
+assert(r2.upstream_resource() == expected);
+assert(r3.upstream_resource() == expected);
+}
+
+expected = std::experimental::pmr::new_delete_resource();
+std::experimental::pmr::set_default_resource(expected);
+{
+char buffer[16];
+std::experimental::pmr::monotonic_buffer_resource r1;
+std::experimental::pmr::monotonic_buffer_resource r2(16);
+std::experimental::pmr::monotonic_buffer_resource r3(buffer, sizeof buffer);
+assert(r1.upstream_resource() == expected);
+assert(r2.upstream_resource() == expected);
+assert(r3.upstream_resource() == expected);
+}
+}
+
+void test_construction_without_buffer()
+{
+// Constructing a monotonic_buffer_resource should not cause allocations
+// by itself; the resource should wait to allocate until an allocation is
+// requested.
+
+globalMemCounter.reset();
+std::experimental::pmr::set_default_resource(std::experimental::pmr::new_delete_resource());
+
+std::experimental::pmr::monotonic_buffer_resource r1;
+assert(globalMemCounter.checkNewCalledEq(0));
+
+std::experimental::pmr::monotonic_buffer_resource r2(1024);
+assert(globalMemCounter.checkNewCalledEq(0));
+
+std::experimental::pmr::monotonic_buffer_resource r3(1024, std::experimental::pmr::new_delete_resource());
+assert(globalMemCounter.checkNewCalledEq(0));
+}
+
+void test_equality()
+{
+// Same object
+{
+std::experimental::pmr::monotonic_buffer_resource r1;
+std::experimental::pmr::monotonic_buffer_resource r2;
+assert(r1 == r1);
+assert(r1 != r2);
+
+std::experimental::pmr::memory_resource & p1 = r1;
+std::experimental::pmr::memory_resource & p2 = r2;
+assert(p1 == p1);
+assert(p1 != p2);
+assert(p1 == r1);
+assert(r1 == p1);
+assert(p1 != r2);
+assert(r2 != p1);
+}
+// Different types
+{
+std::experimental::pmr::monotonic_buffer_resource mono1;
+std::experimental::pmr::memory_resource & r1 = mono1;
+assert_on_compare c;
+std::experimental::pmr::memory_resource & r2 = c;
+

[PATCH] D47103: Implement strip.invariant.group

2018-05-19 Thread Dávid Bolvanský via Phabricator via cfe-commits
xbolva00 added inline comments.



Comment at: clang/include/clang/AST/DeclCXX.h:778
 
+  bool mayBeDynamicClass() const {
+return !isCompleteDefinition() || isDynamicClass();

maybeDynamicClass?

https://github.com/llvm-mirror/llvm/search?utf8=%E2%9C%93=maybe=


Repository:
  rL LLVM

https://reviews.llvm.org/D47103



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


[PATCH] D47103: Implement strip.invariant.group

2018-05-19 Thread Piotr Padlewski via Phabricator via cfe-commits
Prazek updated this revision to Diff 147683.
Prazek added a comment.

introduced mayBeDynamicClass and added more tests


Repository:
  rL LLVM

https://reviews.llvm.org/D47103

Files:
  clang/include/clang/AST/DeclCXX.h
  clang/lib/CodeGen/CGExpr.cpp
  clang/lib/CodeGen/CGExprScalar.cpp
  clang/test/CodeGenCXX/strict-vtable-pointers.cpp
  llvm/docs/LangRef.rst
  llvm/include/llvm/IR/IRBuilder.h
  llvm/include/llvm/IR/Intrinsics.td
  llvm/lib/Analysis/CaptureTracking.cpp
  llvm/lib/Analysis/ConstantFolding.cpp
  llvm/lib/Analysis/ValueTracking.cpp
  llvm/lib/CodeGen/CodeGenPrepare.cpp
  llvm/lib/CodeGen/SelectionDAG/FastISel.cpp
  llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp
  llvm/lib/IR/Value.cpp
  llvm/lib/Target/AMDGPU/AMDGPUPromoteAlloca.cpp
  llvm/test/Analysis/ValueTracking/invariant.group.ll
  llvm/test/CodeGen/Generic/intrinsics.ll
  llvm/test/Other/invariant.group.ll
  llvm/test/Other/launder.invariant.group.ll
  llvm/test/Transforms/CodeGenPrepare/invariant.group.ll
  llvm/test/Transforms/DeadStoreElimination/launder.invariant.group.ll
  llvm/test/Transforms/FunctionAttrs/nocapture.ll
  llvm/test/Transforms/GVN/invariant.group.ll
  llvm/test/Transforms/GlobalOpt/invariant.group.barrier.ll
  llvm/test/Transforms/GlobalOpt/invariant.group.ll
  llvm/test/Transforms/InstCombine/invariant.group.ll
  llvm/test/Transforms/NewGVN/invariant.group.ll

Index: llvm/test/Transforms/NewGVN/invariant.group.ll
===
--- llvm/test/Transforms/NewGVN/invariant.group.ll
+++ llvm/test/Transforms/NewGVN/invariant.group.ll
@@ -52,6 +52,19 @@
 ret i8 %b
 }
 
+; CHECK-LABEL: define i1 @proveEqualityForStrip(
+define i1 @proveEqualityForStrip(i8* %a) {
+; FIXME: The first call could be also removed by GVN. Right now
+; DCE removes it. The second call is CSE'd with the first one.
+; CHECK: %b1 = call i8* @llvm.strip.invariant.group.p0i8(i8* %a)
+  %b1 = call i8* @llvm.strip.invariant.group.p0i8(i8* %a)
+; CHECK-NOT: llvm.strip.invariant.group
+  %b2 = call i8* @llvm.strip.invariant.group.p0i8(i8* %a)
+  %r = icmp eq i8* %b1, %b2
+; CHECK: ret i1 true
+  ret i1 %r
+}
+
 ; CHECK-LABEL: define i8 @unoptimizable1() {
 define i8 @unoptimizable1() {
 entry:
Index: llvm/test/Transforms/InstCombine/invariant.group.ll
===
--- llvm/test/Transforms/InstCombine/invariant.group.ll
+++ llvm/test/Transforms/InstCombine/invariant.group.ll
@@ -1,5 +1,6 @@
 ; RUN: opt -instcombine -S < %s | FileCheck %s
 
+
 ; CHECK-LABEL: define i8* @simplifyNullLaunder()
 define i8* @simplifyNullLaunder() {
 ; CHECK-NEXT: ret i8* null
@@ -29,6 +30,39 @@
   ret i8 addrspace(42)* %b2
 }
 
-
 declare i8* @llvm.launder.invariant.group.p0i8(i8*)
 declare i8 addrspace(42)* @llvm.launder.invariant.group.p42i8(i8 addrspace(42)*)
+
+
+; CHECK-LABEL: define i8* @simplifyNullStrip()
+define i8* @simplifyNullStrip() {
+; CHECK-NEXT: ret i8* null
+  %b2 = call i8* @llvm.strip.invariant.group.p0i8(i8* null)
+  ret i8* %b2
+}
+
+; CHECK-LABEL: define i8 addrspace(42)* @dontsimplifyNullStripForDifferentAddrspace()
+define i8 addrspace(42)* @dontsimplifyNullStripForDifferentAddrspace() {
+; CHECK: %b2 = call i8 addrspace(42)* @llvm.strip.invariant.group.p42i8(i8 addrspace(42)* null)
+; CHECK: ret i8 addrspace(42)* %b2
+  %b2 = call i8 addrspace(42)* @llvm.strip.invariant.group.p42i8(i8 addrspace(42)* null)
+  ret i8 addrspace(42)* %b2
+}
+
+; CHECK-LABEL: define i8* @simplifyUndefStrip()
+define i8* @simplifyUndefStrip() {
+; CHECK-NEXT: ret i8* undef
+  %b2 = call i8* @llvm.strip.invariant.group.p0i8(i8* undef)
+  ret i8* %b2
+}
+
+; CHECK-LABEL: define i8 addrspace(42)* @simplifyUndefStrip2()
+define i8 addrspace(42)* @simplifyUndefStrip2() {
+; CHECK-NEXT: ret i8 addrspace(42)* undef
+  %b2 = call i8 addrspace(42)* @llvm.strip.invariant.group.p42i8(i8 addrspace(42)* undef)
+  ret i8 addrspace(42)* %b2
+}
+
+declare i8* @llvm.strip.invariant.group.p0i8(i8*)
+declare i8 addrspace(42)* @llvm.strip.invariant.group.p42i8(i8 addrspace(42)*)
+
Index: llvm/test/Transforms/GlobalOpt/invariant.group.ll
===
--- llvm/test/Transforms/GlobalOpt/invariant.group.ll
+++ llvm/test/Transforms/GlobalOpt/invariant.group.ll
@@ -27,46 +27,46 @@
 define void @_optimizable() {
 enter:
   %valptr = alloca i32
-  
+
   %val = call i32 @TheAnswerToLifeTheUniverseAndEverything()
   store i32 %val, i32* @tmp
   store i32 %val, i32* %valptr
-  
+
   %0 = bitcast i32* %valptr to i8*
   %barr = call i8* @llvm.launder.invariant.group(i8* %0)
   %1 = bitcast i8* %barr to i32*
-  
+
   %val2 = load i32, i32* %1
   store i32 %val2, i32* @tmp2
   ret void
 }
 
 ; We can't step through launder.invariant.group here, because that would change
 ; this load in @usage_of_globals()
-; val = load i32, i32* %ptrVal, !invariant.group !0 
-; into 
+; val = load i32, i32* %ptrVal, !invariant.group !0
+; into
 ; %val 

[PATCH] D47099: Disable casting of alloca for ActiveFlag

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

In https://reviews.llvm.org/D47099#1105574, @yaxunl wrote:

> In https://reviews.llvm.org/D47099#1105493, @rjmccall wrote:
>
> > Maybe there should just be a method that makes a primitive alloca without 
> > the casting, and then you can call that in CreateTempAlloca.
>
>
> In many cases we still need to call CreateTempAlloca with cast enabled, since 
> we are not certain there is only load from it and store to it. Any time it is 
> stored to another memory location or passed to another function (e.g. 
> constructor/destructor), it needs to be a pointer to  the language's default 
> address space since the language sees it that way.


Yes, I understand that.  But there are some cases, like this, that do not need 
to produce something in `LangAS::Default`, and extracting out a method that 
just does an `alloca` without the unnecessary cast seems sensible.

> An alternative fix would be just let ActiveFlag to be llvm::Value instead of 
> llvm::AllocaInst, since it does not really need to be an AllocaInst.

I don't care at all about the type of `ActiveFlag`, but if we can generate 
better code at -O0 by avoiding the casts in situations where we obviously don't 
need them, we should do it.


https://reviews.llvm.org/D47099



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


[PATCH] D47108: Add -fforce-emit-vtable

2018-05-19 Thread Piotr Padlewski via Phabricator via cfe-commits
Prazek updated this revision to Diff 147679.
Prazek added a comment.

Fixed flag passing


Repository:
  rL LLVM

https://reviews.llvm.org/D47108

Files:
  clang/docs/ClangCommandLineReference.rst
  clang/docs/ReleaseNotes.rst
  clang/docs/UsersManual.rst
  clang/include/clang/Driver/Options.td
  clang/include/clang/Frontend/CodeGenOptions.def
  clang/lib/CodeGen/ItaniumCXXABI.cpp
  clang/lib/Driver/ToolChains/Clang.cpp
  clang/lib/Frontend/CompilerInvocation.cpp
  clang/test/CodeGenCXX/vtable-available-externally.cpp

Index: clang/test/CodeGenCXX/vtable-available-externally.cpp
===
--- clang/test/CodeGenCXX/vtable-available-externally.cpp
+++ clang/test/CodeGenCXX/vtable-available-externally.cpp
@@ -1,5 +1,6 @@
 // RUN: %clang_cc1 %s -I%S -triple=x86_64-apple-darwin10 -std=c++98 -emit-llvm -o %t
 // RUN: %clang_cc1 %s -I%S -triple=x86_64-apple-darwin10 -std=c++98 -O2 -disable-llvm-passes -emit-llvm -o %t.opt
+// RUN: %clang_cc1 %s -I%S -triple=x86_64-apple-darwin10 -std=c++98 -O2 -disable-llvm-passes -emit-llvm -o %t.vtable -fforce-emit-vtables
 // RUN: FileCheck --check-prefix=CHECK-TEST1 %s < %t
 // RUN: FileCheck --check-prefix=CHECK-TEST2 %s < %t
 // RUN: FileCheck --check-prefix=CHECK-TEST5 %s < %t
@@ -13,10 +14,13 @@
 // RUN: FileCheck --check-prefix=CHECK-TEST15 %s < %t.opt
 // RUN: FileCheck --check-prefix=CHECK-TEST16 %s < %t.opt
 // RUN: FileCheck --check-prefix=CHECK-TEST17 %s < %t.opt
+// RUN: FileCheck --check-prefix=CHECK-FORCE-EMIT %s < %t.vtable
+
 
 #include 
 
 // CHECK-TEST1: @_ZTVN5Test11AE = external unnamed_addr constant
+// CHECK-FORCE-EMIT-DAG: @_ZTVN5Test11AE = available_externally unnamed_addr constant
 namespace Test1 {
 
 struct A {
@@ -213,14 +217,16 @@
 
 // because A's key function is defined here, vtable is generated in this TU
 // CHECK-TEST10-DAG: @_ZTVN6Test101AE = unnamed_addr constant
+// CHECK-FORCE-EMIT-DAG: @_ZTVN6Test101AE = unnamed_addr constant
 struct A {
   virtual void foo();
   virtual void bar();
 };
 void A::foo() {}
 
 // Because key function is inline we will generate vtable as linkonce_odr.
 // CHECK-TEST10-DAG: @_ZTVN6Test101DE = linkonce_odr unnamed_addr constant
+// CHECK-FORCE-EMIT-DAG: @_ZTVN6Test101DE = linkonce_odr unnamed_addr constant
 struct D : A {
   void bar();
 };
@@ -237,14 +243,17 @@
 // can't guarantee that we will be able to refer to bar from name
 // so (at the moment) we can't emit vtable available_externally.
 // CHECK-TEST10-DAG: @_ZTVN6Test101CE = external unnamed_addr constant
+// CHECK-FORCE-EMIT-DAG: @_ZTVN6Test101CE = available_externally unnamed_addr constant
 struct C : A {
   void bar() {}   // defined in body - not key function
   virtual inline void gar();  // inline in body - not key function
   virtual void car();
 };
 
 // no key function, vtable will be generated everywhere it will be used
 // CHECK-TEST10-DAG: @_ZTVN6Test101EE = linkonce_odr unnamed_addr constant
+// CHECK-FORCE-EMIT-DAG: @_ZTVN6Test101EE = linkonce_odr unnamed_addr constant
+
 struct E : A {};
 
 void g(A& a) {
@@ -298,11 +307,13 @@
 namespace Test12 {
 
 // CHECK-TEST12: @_ZTVN6Test121AE = external unnamed_addr constant
+// CHECK-FORCE-EMIT-DAG: @_ZTVN6Test121AE = available_externally unnamed_addr constant
 struct A {
   virtual void foo();
   virtual ~A() {}
 };
 // CHECK-TEST12: @_ZTVN6Test121BE = external unnamed_addr constant
+// CHECK-FORCE-EMIT-DAG: @_ZTVN6Test121BE = available_externally unnamed_addr constant
 struct B : A {
   void foo();
 };
@@ -319,6 +330,9 @@
 
 // CHECK-TEST13-DAG: @_ZTVN6Test131AE = available_externally unnamed_addr constant
 // CHECK-TEST13-DAG: @_ZTVN6Test131BE = external unnamed_addr constant
+// CHECK-FORCE-EMIT-DAG: @_ZTVN6Test131AE = available_externally unnamed_addr constant
+// CHECK-FORCE-EMIT-DAG: @_ZTVN6Test131BE = available_externally unnamed_addr constant
+
 struct A {
   virtual ~A();
 };
@@ -371,6 +385,8 @@
 // generate available_externally vtable for it.
 // CHECK-TEST16-DAG: @_ZTVN6Test161SE = external unnamed_addr constant
 // CHECK-TEST16-DAG: @_ZTVN6Test162S2E = available_externally
+// CHECK-FORCE-EMIT-DAG: @_ZTVN6Test161SE = external unnamed_addr constant
+// CHECK-FORCE-EMIT-DAG: @_ZTVN6Test162S2E = available_externally
 
 struct S {
   __attribute__((visibility("hidden"))) virtual void doStuff();
@@ -395,6 +411,10 @@
 // This test checks if we emit vtables opportunistically.
 // CHECK-TEST17-DAG: @_ZTVN6Test171AE = available_externally
 // CHECK-TEST17-DAG: @_ZTVN6Test171BE = external
+// CHECK-FORCE-EMIT-DAG: @_ZTVN6Test171AE = available_externally
+// CHECK-FORCE-EMIT-DAG: @_ZTVN6Test171BE = available_externally
+// CHECK-FORCE-EMIT-DAG: define linkonce_odr void @_ZN6Test171BD1Ev(
+// CHECK-FORCE-EMIT-DAG: define linkonce_odr void @_ZN6Test171BD0Ev(
 
 struct A {
   virtual void key();
Index: clang/lib/Frontend/CompilerInvocation.cpp
===
--- 

[PATCH] D46806: Remove unused code from __functional_base. NFC.

2018-05-19 Thread Arthur O'Dwyer via Phabricator via cfe-commits
Quuxplusone added inline comments.



Comment at: include/experimental/memory_resource:99
 // 8.5, memory.resource
-class _LIBCPP_TEMPLATE_VIS memory_resource
+class _LIBCPP_TYPE_VIS memory_resource
 {

...although maybe I don't understand the rules here. For example, I see 
`allocator_arg_t` and `monostate` are both marked `_LIBCPP_TEMPLATE_VIS` as 
well, even though they're not templates.


Repository:
  rCXX libc++

https://reviews.llvm.org/D46806



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


[PATCH] D46806: Remove unused code from __functional_base. NFC.

2018-05-19 Thread Arthur O'Dwyer via Phabricator via cfe-commits
Quuxplusone updated this revision to Diff 147677.
Quuxplusone added a comment.

@EricWF: would you mind landing these two drive-by fixes while you're at it?


Repository:
  rCXX libc++

https://reviews.llvm.org/D46806

Files:
  include/__functional_base
  include/experimental/memory_resource


Index: include/experimental/memory_resource
===
--- include/experimental/memory_resource
+++ include/experimental/memory_resource
@@ -96,7 +96,7 @@
 }
 
 // 8.5, memory.resource
-class _LIBCPP_TEMPLATE_VIS memory_resource
+class _LIBCPP_TYPE_VIS memory_resource
 {
 static const size_t __max_align = alignof(max_align_t);
 
Index: include/__functional_base
===
--- include/__functional_base
+++ include/__functional_base
@@ -646,16 +646,6 @@
 new (__storage) _Tp (_VSTD::forward<_Args>(__args)..., __a);
 }
 
-// FIXME: Theis should have a version which takes a non-const alloc.
-template 
-inline _LIBCPP_INLINE_VISIBILITY
-void __user_alloc_construct (_Tp *__storage, const _Allocator &__a, _Args 
&&... __args)
-{ 
-__user_alloc_construct_impl( 
- __uses_alloc_ctor<_Tp, _Allocator>(), 
- __storage, __a, _VSTD::forward<_Args>(__args)...
-);
-}
 #endif  // _LIBCPP_CXX03_LANG
 
 _LIBCPP_END_NAMESPACE_STD


Index: include/experimental/memory_resource
===
--- include/experimental/memory_resource
+++ include/experimental/memory_resource
@@ -96,7 +96,7 @@
 }
 
 // 8.5, memory.resource
-class _LIBCPP_TEMPLATE_VIS memory_resource
+class _LIBCPP_TYPE_VIS memory_resource
 {
 static const size_t __max_align = alignof(max_align_t);
 
Index: include/__functional_base
===
--- include/__functional_base
+++ include/__functional_base
@@ -646,16 +646,6 @@
 new (__storage) _Tp (_VSTD::forward<_Args>(__args)..., __a);
 }
 
-// FIXME: Theis should have a version which takes a non-const alloc.
-template 
-inline _LIBCPP_INLINE_VISIBILITY
-void __user_alloc_construct (_Tp *__storage, const _Allocator &__a, _Args &&... __args)
-{ 
-__user_alloc_construct_impl( 
- __uses_alloc_ctor<_Tp, _Allocator>(), 
- __storage, __a, _VSTD::forward<_Args>(__args)...
-);
-}
 #endif  // _LIBCPP_CXX03_LANG
 
 _LIBCPP_END_NAMESPACE_STD
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D47109: LWG 2969 "polymorphic_allocator::construct() shouldn't pass resource()"

2018-05-19 Thread Arthur O'Dwyer via Phabricator via cfe-commits
Quuxplusone added a comment.

In https://reviews.llvm.org/D47109#1105680, @EricWF wrote:

> This LGTM. Let's land it and see if anybody complains.


Sounds good to me. I don't have commit privs so could you land it for me?
(Besides, I'm happy for you to get the blame if it *does* break someone's code, 
as I suspect it might. ;))


Repository:
  rCXX libc++

https://reviews.llvm.org/D47109



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


[PATCH] D47109: LWG 2969 "polymorphic_allocator::construct() shouldn't pass resource()"

2018-05-19 Thread Eric Fiselier via Phabricator via cfe-commits
EricWF accepted this revision.
EricWF added a comment.
This revision is now accepted and ready to land.

This LGTM. Let's land it and see if anybody complains.


Repository:
  rCXX libc++

https://reviews.llvm.org/D47109



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


[PATCH] D47109: LWG 2969 "polymorphic_allocator::construct() shouldn't pass resource()"

2018-05-19 Thread Arthur O'Dwyer via Phabricator via cfe-commits
Quuxplusone updated this revision to Diff 147676.
Quuxplusone added a comment.
Herald added a subscriber: christof.

Fix two more tests hiding in test/libcxx/, and give -U999 context.


Repository:
  rCXX libc++

https://reviews.llvm.org/D47109

Files:
  include/experimental/memory_resource
  
test/libcxx/experimental/memory/memory.polymorphic.allocator.class/memory.polymorphic.allocator.mem/construct_piecewise_pair.pass.cpp
  
test/std/experimental/memory/memory.polymorphic.allocator.class/memory.polymorphic.allocator.mem/construct_pair_const_lvalue_pair.pass.cpp
  
test/std/experimental/memory/memory.polymorphic.allocator.class/memory.polymorphic.allocator.mem/construct_pair_rvalue.pass.cpp
  
test/std/experimental/memory/memory.polymorphic.allocator.class/memory.polymorphic.allocator.mem/construct_pair_values.pass.cpp
  
test/std/experimental/memory/memory.polymorphic.allocator.class/memory.polymorphic.allocator.mem/construct_piecewise_pair.pass.cpp
  
test/std/experimental/memory/memory.polymorphic.allocator.class/memory.polymorphic.allocator.mem/construct_piecewise_pair_evil.pass.cpp
  
test/std/experimental/memory/memory.polymorphic.allocator.class/memory.polymorphic.allocator.mem/construct_types.pass.cpp
  test/support/test_memory_resource.hpp

Index: test/support/test_memory_resource.hpp
===
--- test/support/test_memory_resource.hpp
+++ test/support/test_memory_resource.hpp
@@ -28,7 +28,7 @@
 // because it can't include 
 template <>
 struct TransformErasedTypeAlloc {
-  using type = std::experimental::pmr::memory_resource*;
+  using type = std::experimental::pmr::polymorphic_allocator;
 };
 
 template 
Index: test/std/experimental/memory/memory.polymorphic.allocator.class/memory.polymorphic.allocator.mem/construct_types.pass.cpp
===
--- test/std/experimental/memory/memory.polymorphic.allocator.class/memory.polymorphic.allocator.mem/construct_types.pass.cpp
+++ test/std/experimental/memory/memory.polymorphic.allocator.class/memory.polymorphic.allocator.mem/construct_types.pass.cpp
@@ -126,6 +126,39 @@
 }
 }
 
+template 
+void test_pmr_not_uses_alloc(Args&&... args)
+{
+TestResource R(12435);
+ex::memory_resource* M = 
+{
+// NotUsesAllocator provides valid signatures for each uses-allocator
+// construction but does not supply the required allocator_type typedef.
+// Test that we can call these constructors manually without
+// polymorphic_allocator interfering.
+using T = NotUsesAllocator;
+assert(doTestUsesAllocV0(std::forward(args)...));
+assert((doTestUsesAllocV1(M, std::forward(args)...)));
+assert((doTestUsesAllocV2(M, std::forward(args)...)));
+}
+{
+// Test T(std::allocator_arg_t, Alloc const&, Args...) construction
+using T = UsesAllocatorV1;
+assert((doTest(UA_None, std::forward(args)...)));
+}
+{
+// Test T(Args..., Alloc const&) construction
+using T = UsesAllocatorV2;
+assert((doTest(UA_None, std::forward(args)...)));
+}
+{
+// Test that T(std::allocator_arg_t, Alloc const&, Args...) construction
+// is preferred when T(Args..., Alloc const&) is also available.
+using T = UsesAllocatorV3;
+assert((doTest(UA_None, std::forward(args)...)));
+}
+}
+
 // Test that polymorphic_allocator does not prevent us from manually
 // doing non-pmr uses-allocator construction.
 template 
@@ -167,16 +200,16 @@
 const int cvalue = 43;
 {
 test_pmr_uses_alloc();
-test_pmr_uses_alloc();
+test_pmr_not_uses_alloc();
 test_pmr_uses_alloc();
 test_pmr_uses_alloc(value);
-test_pmr_uses_alloc(value);
+test_pmr_not_uses_alloc(value);
 test_pmr_uses_alloc(value);
 test_pmr_uses_alloc(cvalue);
-test_pmr_uses_alloc(cvalue);
+test_pmr_not_uses_alloc(cvalue);
 test_pmr_uses_alloc(cvalue);
 test_pmr_uses_alloc(cvalue, std::move(value));
-test_pmr_uses_alloc(cvalue, std::move(value));
+test_pmr_not_uses_alloc(cvalue, std::move(value));
 test_pmr_uses_alloc(cvalue, std::move(value));
 }
 {
Index: test/std/experimental/memory/memory.polymorphic.allocator.class/memory.polymorphic.allocator.mem/construct_piecewise_pair_evil.pass.cpp
===
--- /dev/null
+++ test/std/experimental/memory/memory.polymorphic.allocator.class/memory.polymorphic.allocator.mem/construct_piecewise_pair_evil.pass.cpp
@@ -0,0 +1,141 @@
+//===--===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University 

[PATCH] D47109: LWG 2969 "polymorphic_allocator::construct() shouldn't pass resource()"

2018-05-19 Thread Arthur O'Dwyer via Phabricator via cfe-commits
Quuxplusone created this revision.
Quuxplusone added a reviewer: EricWF.
Herald added a subscriber: cfe-commits.

In the TS, `uses_allocator` construction for `pair` tried to use an allocator 
type of `memory_resource*`, which is incorrect because `memory_resource*` is 
not an allocator type. LWG 2969 fixed it to use `polymorphic_allocator` as the 
allocator type instead.
https://wg21.link/lwg2969

(https://reviews.llvm.org/D47090 included this in ``; at 
Eric's request, I've split this out into its own patch applied to the existing 
`` instead.)


Repository:
  rCXX libc++

https://reviews.llvm.org/D47109

Files:
  include/experimental/memory_resource
  
test/std/experimental/memory/memory.polymorphic.allocator.class/memory.polymorphic.allocator.mem/construct_pair_const_lvalue_pair.pass.cpp
  
test/std/experimental/memory/memory.polymorphic.allocator.class/memory.polymorphic.allocator.mem/construct_pair_rvalue.pass.cpp
  
test/std/experimental/memory/memory.polymorphic.allocator.class/memory.polymorphic.allocator.mem/construct_pair_values.pass.cpp
  
test/std/experimental/memory/memory.polymorphic.allocator.class/memory.polymorphic.allocator.mem/construct_piecewise_pair.pass.cpp
  
test/std/experimental/memory/memory.polymorphic.allocator.class/memory.polymorphic.allocator.mem/construct_piecewise_pair_evil.pass.cpp
  
test/std/experimental/memory/memory.polymorphic.allocator.class/memory.polymorphic.allocator.mem/construct_types.pass.cpp
  test/support/test_memory_resource.hpp

Index: test/support/test_memory_resource.hpp
===
--- test/support/test_memory_resource.hpp
+++ test/support/test_memory_resource.hpp
@@ -28,7 +28,7 @@
 // because it can't include 
 template <>
 struct TransformErasedTypeAlloc {
-  using type = std::experimental::pmr::memory_resource*;
+  using type = std::experimental::pmr::polymorphic_allocator;
 };
 
 template 
Index: test/std/experimental/memory/memory.polymorphic.allocator.class/memory.polymorphic.allocator.mem/construct_types.pass.cpp
===
--- test/std/experimental/memory/memory.polymorphic.allocator.class/memory.polymorphic.allocator.mem/construct_types.pass.cpp
+++ test/std/experimental/memory/memory.polymorphic.allocator.class/memory.polymorphic.allocator.mem/construct_types.pass.cpp
@@ -126,6 +126,39 @@
 }
 }
 
+template 
+void test_pmr_not_uses_alloc(Args&&... args)
+{
+TestResource R(12435);
+ex::memory_resource* M = 
+{
+// NotUsesAllocator provides valid signatures for each uses-allocator
+// construction but does not supply the required allocator_type typedef.
+// Test that we can call these constructors manually without
+// polymorphic_allocator interfering.
+using T = NotUsesAllocator;
+assert(doTestUsesAllocV0(std::forward(args)...));
+assert((doTestUsesAllocV1(M, std::forward(args)...)));
+assert((doTestUsesAllocV2(M, std::forward(args)...)));
+}
+{
+// Test T(std::allocator_arg_t, Alloc const&, Args...) construction
+using T = UsesAllocatorV1;
+assert((doTest(UA_None, std::forward(args)...)));
+}
+{
+// Test T(Args..., Alloc const&) construction
+using T = UsesAllocatorV2;
+assert((doTest(UA_None, std::forward(args)...)));
+}
+{
+// Test that T(std::allocator_arg_t, Alloc const&, Args...) construction
+// is preferred when T(Args..., Alloc const&) is also available.
+using T = UsesAllocatorV3;
+assert((doTest(UA_None, std::forward(args)...)));
+}
+}
+
 // Test that polymorphic_allocator does not prevent us from manually
 // doing non-pmr uses-allocator construction.
 template 
@@ -167,16 +200,16 @@
 const int cvalue = 43;
 {
 test_pmr_uses_alloc();
-test_pmr_uses_alloc();
+test_pmr_not_uses_alloc();
 test_pmr_uses_alloc();
 test_pmr_uses_alloc(value);
-test_pmr_uses_alloc(value);
+test_pmr_not_uses_alloc(value);
 test_pmr_uses_alloc(value);
 test_pmr_uses_alloc(cvalue);
-test_pmr_uses_alloc(cvalue);
+test_pmr_not_uses_alloc(cvalue);
 test_pmr_uses_alloc(cvalue);
 test_pmr_uses_alloc(cvalue, std::move(value));
-test_pmr_uses_alloc(cvalue, std::move(value));
+test_pmr_not_uses_alloc(cvalue, std::move(value));
 test_pmr_uses_alloc(cvalue, std::move(value));
 }
 {
Index: test/std/experimental/memory/memory.polymorphic.allocator.class/memory.polymorphic.allocator.mem/construct_piecewise_pair_evil.pass.cpp
===
--- /dev/null
+++ 

[PATCH] D47108: Add -fforce-emit-vtable

2018-05-19 Thread Piotr Padlewski via Phabricator via cfe-commits
Prazek updated this revision to Diff 147675.
Prazek added a comment.

Fixed comment


Repository:
  rL LLVM

https://reviews.llvm.org/D47108

Files:
  clang/docs/ClangCommandLineReference.rst
  clang/docs/ReleaseNotes.rst
  clang/docs/UsersManual.rst
  clang/include/clang/Driver/Options.td
  clang/include/clang/Frontend/CodeGenOptions.def
  clang/lib/CodeGen/ItaniumCXXABI.cpp
  clang/lib/Driver/ToolChains/Clang.cpp
  clang/lib/Frontend/CompilerInvocation.cpp
  clang/test/CodeGenCXX/vtable-available-externally.cpp

Index: clang/test/CodeGenCXX/vtable-available-externally.cpp
===
--- clang/test/CodeGenCXX/vtable-available-externally.cpp
+++ clang/test/CodeGenCXX/vtable-available-externally.cpp
@@ -1,5 +1,6 @@
 // RUN: %clang_cc1 %s -I%S -triple=x86_64-apple-darwin10 -std=c++98 -emit-llvm -o %t
 // RUN: %clang_cc1 %s -I%S -triple=x86_64-apple-darwin10 -std=c++98 -O2 -disable-llvm-passes -emit-llvm -o %t.opt
+// RUN: %clang_cc1 %s -I%S -triple=x86_64-apple-darwin10 -std=c++98 -O2 -disable-llvm-passes -emit-llvm -o %t.vtable -fforce-emit-vtables
 // RUN: FileCheck --check-prefix=CHECK-TEST1 %s < %t
 // RUN: FileCheck --check-prefix=CHECK-TEST2 %s < %t
 // RUN: FileCheck --check-prefix=CHECK-TEST5 %s < %t
@@ -13,10 +14,13 @@
 // RUN: FileCheck --check-prefix=CHECK-TEST15 %s < %t.opt
 // RUN: FileCheck --check-prefix=CHECK-TEST16 %s < %t.opt
 // RUN: FileCheck --check-prefix=CHECK-TEST17 %s < %t.opt
+// RUN: FileCheck --check-prefix=CHECK-FORCE-EMIT %s < %t.vtable
+
 
 #include 
 
 // CHECK-TEST1: @_ZTVN5Test11AE = external unnamed_addr constant
+// CHECK-FORCE-EMIT-DAG: @_ZTVN5Test11AE = available_externally unnamed_addr constant
 namespace Test1 {
 
 struct A {
@@ -213,14 +217,16 @@
 
 // because A's key function is defined here, vtable is generated in this TU
 // CHECK-TEST10-DAG: @_ZTVN6Test101AE = unnamed_addr constant
+// CHECK-FORCE-EMIT-DAG: @_ZTVN6Test101AE = unnamed_addr constant
 struct A {
   virtual void foo();
   virtual void bar();
 };
 void A::foo() {}
 
 // Because key function is inline we will generate vtable as linkonce_odr.
 // CHECK-TEST10-DAG: @_ZTVN6Test101DE = linkonce_odr unnamed_addr constant
+// CHECK-FORCE-EMIT-DAG: @_ZTVN6Test101DE = linkonce_odr unnamed_addr constant
 struct D : A {
   void bar();
 };
@@ -237,14 +243,17 @@
 // can't guarantee that we will be able to refer to bar from name
 // so (at the moment) we can't emit vtable available_externally.
 // CHECK-TEST10-DAG: @_ZTVN6Test101CE = external unnamed_addr constant
+// CHECK-FORCE-EMIT-DAG: @_ZTVN6Test101CE = available_externally unnamed_addr constant
 struct C : A {
   void bar() {}   // defined in body - not key function
   virtual inline void gar();  // inline in body - not key function
   virtual void car();
 };
 
 // no key function, vtable will be generated everywhere it will be used
 // CHECK-TEST10-DAG: @_ZTVN6Test101EE = linkonce_odr unnamed_addr constant
+// CHECK-FORCE-EMIT-DAG: @_ZTVN6Test101EE = linkonce_odr unnamed_addr constant
+
 struct E : A {};
 
 void g(A& a) {
@@ -298,11 +307,13 @@
 namespace Test12 {
 
 // CHECK-TEST12: @_ZTVN6Test121AE = external unnamed_addr constant
+// CHECK-FORCE-EMIT-DAG: @_ZTVN6Test121AE = available_externally unnamed_addr constant
 struct A {
   virtual void foo();
   virtual ~A() {}
 };
 // CHECK-TEST12: @_ZTVN6Test121BE = external unnamed_addr constant
+// CHECK-FORCE-EMIT-DAG: @_ZTVN6Test121BE = available_externally unnamed_addr constant
 struct B : A {
   void foo();
 };
@@ -319,6 +330,9 @@
 
 // CHECK-TEST13-DAG: @_ZTVN6Test131AE = available_externally unnamed_addr constant
 // CHECK-TEST13-DAG: @_ZTVN6Test131BE = external unnamed_addr constant
+// CHECK-FORCE-EMIT-DAG: @_ZTVN6Test131AE = available_externally unnamed_addr constant
+// CHECK-FORCE-EMIT-DAG: @_ZTVN6Test131BE = available_externally unnamed_addr constant
+
 struct A {
   virtual ~A();
 };
@@ -371,6 +385,8 @@
 // generate available_externally vtable for it.
 // CHECK-TEST16-DAG: @_ZTVN6Test161SE = external unnamed_addr constant
 // CHECK-TEST16-DAG: @_ZTVN6Test162S2E = available_externally
+// CHECK-FORCE-EMIT-DAG: @_ZTVN6Test161SE = external unnamed_addr constant
+// CHECK-FORCE-EMIT-DAG: @_ZTVN6Test162S2E = available_externally
 
 struct S {
   __attribute__((visibility("hidden"))) virtual void doStuff();
@@ -395,6 +411,10 @@
 // This test checks if we emit vtables opportunistically.
 // CHECK-TEST17-DAG: @_ZTVN6Test171AE = available_externally
 // CHECK-TEST17-DAG: @_ZTVN6Test171BE = external
+// CHECK-FORCE-EMIT-DAG: @_ZTVN6Test171AE = available_externally
+// CHECK-FORCE-EMIT-DAG: @_ZTVN6Test171BE = available_externally
+// CHECK-FORCE-EMIT-DAG: define linkonce_odr void @_ZN6Test171BD1Ev(
+// CHECK-FORCE-EMIT-DAG: define linkonce_odr void @_ZN6Test171BD0Ev(
 
 struct A {
   virtual void key();
Index: clang/lib/Frontend/CompilerInvocation.cpp
===
--- 

[PATCH] D47108: Add -fforce-emit-vtable

2018-05-19 Thread Piotr Padlewski via Phabricator via cfe-commits
Prazek updated this revision to Diff 147673.
Prazek added a comment.

remove empty line


Repository:
  rL LLVM

https://reviews.llvm.org/D47108

Files:
  clang/docs/ClangCommandLineReference.rst
  clang/docs/ReleaseNotes.rst
  clang/docs/UsersManual.rst
  clang/include/clang/Driver/Options.td
  clang/include/clang/Frontend/CodeGenOptions.def
  clang/lib/CodeGen/ItaniumCXXABI.cpp
  clang/lib/Driver/ToolChains/Clang.cpp
  clang/lib/Frontend/CompilerInvocation.cpp
  clang/test/CodeGenCXX/vtable-available-externally.cpp

Index: clang/test/CodeGenCXX/vtable-available-externally.cpp
===
--- clang/test/CodeGenCXX/vtable-available-externally.cpp
+++ clang/test/CodeGenCXX/vtable-available-externally.cpp
@@ -1,5 +1,6 @@
 // RUN: %clang_cc1 %s -I%S -triple=x86_64-apple-darwin10 -std=c++98 -emit-llvm -o %t
 // RUN: %clang_cc1 %s -I%S -triple=x86_64-apple-darwin10 -std=c++98 -O2 -disable-llvm-passes -emit-llvm -o %t.opt
+// RUN: %clang_cc1 %s -I%S -triple=x86_64-apple-darwin10 -std=c++98 -O2 -disable-llvm-passes -emit-llvm -o %t.vtable -fforce-emit-vtables
 // RUN: FileCheck --check-prefix=CHECK-TEST1 %s < %t
 // RUN: FileCheck --check-prefix=CHECK-TEST2 %s < %t
 // RUN: FileCheck --check-prefix=CHECK-TEST5 %s < %t
@@ -13,10 +14,13 @@
 // RUN: FileCheck --check-prefix=CHECK-TEST15 %s < %t.opt
 // RUN: FileCheck --check-prefix=CHECK-TEST16 %s < %t.opt
 // RUN: FileCheck --check-prefix=CHECK-TEST17 %s < %t.opt
+// RUN: FileCheck --check-prefix=CHECK-FORCE-EMIT %s < %t.vtable
+
 
 #include 
 
 // CHECK-TEST1: @_ZTVN5Test11AE = external unnamed_addr constant
+// CHECK-FORCE-EMIT-DAG: @_ZTVN5Test11AE = available_externally unnamed_addr constant
 namespace Test1 {
 
 struct A {
@@ -213,14 +217,16 @@
 
 // because A's key function is defined here, vtable is generated in this TU
 // CHECK-TEST10-DAG: @_ZTVN6Test101AE = unnamed_addr constant
+// CHECK-FORCE-EMIT-DAG: @_ZTVN6Test101AE = unnamed_addr constant
 struct A {
   virtual void foo();
   virtual void bar();
 };
 void A::foo() {}
 
 // Because key function is inline we will generate vtable as linkonce_odr.
 // CHECK-TEST10-DAG: @_ZTVN6Test101DE = linkonce_odr unnamed_addr constant
+// CHECK-FORCE-EMIT-DAG: @_ZTVN6Test101DE = linkonce_odr unnamed_addr constant
 struct D : A {
   void bar();
 };
@@ -237,14 +243,17 @@
 // can't guarantee that we will be able to refer to bar from name
 // so (at the moment) we can't emit vtable available_externally.
 // CHECK-TEST10-DAG: @_ZTVN6Test101CE = external unnamed_addr constant
+// CHECK-FORCE-EMIT-DAG: @_ZTVN6Test101CE = available_externally unnamed_addr constant
 struct C : A {
   void bar() {}   // defined in body - not key function
   virtual inline void gar();  // inline in body - not key function
   virtual void car();
 };
 
 // no key function, vtable will be generated everywhere it will be used
 // CHECK-TEST10-DAG: @_ZTVN6Test101EE = linkonce_odr unnamed_addr constant
+// CHECK-FORCE-EMIT-DAG: @_ZTVN6Test101EE = linkonce_odr unnamed_addr constant
+
 struct E : A {};
 
 void g(A& a) {
@@ -298,11 +307,13 @@
 namespace Test12 {
 
 // CHECK-TEST12: @_ZTVN6Test121AE = external unnamed_addr constant
+// CHECK-FORCE-EMIT-DAG: @_ZTVN6Test121AE = available_externally unnamed_addr constant
 struct A {
   virtual void foo();
   virtual ~A() {}
 };
 // CHECK-TEST12: @_ZTVN6Test121BE = external unnamed_addr constant
+// CHECK-FORCE-EMIT-DAG: @_ZTVN6Test121BE = available_externally unnamed_addr constant
 struct B : A {
   void foo();
 };
@@ -319,6 +330,9 @@
 
 // CHECK-TEST13-DAG: @_ZTVN6Test131AE = available_externally unnamed_addr constant
 // CHECK-TEST13-DAG: @_ZTVN6Test131BE = external unnamed_addr constant
+// CHECK-FORCE-EMIT-DAG: @_ZTVN6Test131AE = available_externally unnamed_addr constant
+// CHECK-FORCE-EMIT-DAG: @_ZTVN6Test131BE = available_externally unnamed_addr constant
+
 struct A {
   virtual ~A();
 };
@@ -371,6 +385,8 @@
 // generate available_externally vtable for it.
 // CHECK-TEST16-DAG: @_ZTVN6Test161SE = external unnamed_addr constant
 // CHECK-TEST16-DAG: @_ZTVN6Test162S2E = available_externally
+// CHECK-FORCE-EMIT-DAG: @_ZTVN6Test161SE = external unnamed_addr constant
+// CHECK-FORCE-EMIT-DAG: @_ZTVN6Test162S2E = available_externally
 
 struct S {
   __attribute__((visibility("hidden"))) virtual void doStuff();
@@ -395,6 +411,10 @@
 // This test checks if we emit vtables opportunistically.
 // CHECK-TEST17-DAG: @_ZTVN6Test171AE = available_externally
 // CHECK-TEST17-DAG: @_ZTVN6Test171BE = external
+// CHECK-FORCE-EMIT-DAG: @_ZTVN6Test171AE = available_externally
+// CHECK-FORCE-EMIT-DAG: @_ZTVN6Test171BE = available_externally
+// CHECK-FORCE-EMIT-DAG: define linkonce_odr void @_ZN6Test171BD1Ev(
+// CHECK-FORCE-EMIT-DAG: define linkonce_odr void @_ZN6Test171BD0Ev(
 
 struct A {
   virtual void key();
Index: clang/lib/Frontend/CompilerInvocation.cpp
===
--- 

[PATCH] D47108: Add -fforce-emit-vtable

2018-05-19 Thread Piotr Padlewski via Phabricator via cfe-commits
Prazek updated this revision to Diff 147672.
Prazek added a comment.

Add release note


Repository:
  rL LLVM

https://reviews.llvm.org/D47108

Files:
  clang/docs/ClangCommandLineReference.rst
  clang/docs/ReleaseNotes.rst
  clang/docs/UsersManual.rst
  clang/include/clang/Driver/Options.td
  clang/include/clang/Frontend/CodeGenOptions.def
  clang/lib/CodeGen/ItaniumCXXABI.cpp
  clang/lib/Driver/ToolChains/Clang.cpp
  clang/lib/Frontend/CompilerInvocation.cpp
  clang/test/CodeGenCXX/vtable-available-externally.cpp
  clang/test/CodeGenCXX/vtable-linkage.cpp

Index: clang/test/CodeGenCXX/vtable-linkage.cpp
===
--- clang/test/CodeGenCXX/vtable-linkage.cpp
+++ clang/test/CodeGenCXX/vtable-linkage.cpp
@@ -7,6 +7,7 @@
 // RUN: FileCheck %s < %t.11
 // RUN: FileCheck --check-prefix=CHECK-OPT %s < %t.opt
 
+
 namespace {
   struct A {
 virtual void f() { }
Index: clang/test/CodeGenCXX/vtable-available-externally.cpp
===
--- clang/test/CodeGenCXX/vtable-available-externally.cpp
+++ clang/test/CodeGenCXX/vtable-available-externally.cpp
@@ -1,5 +1,6 @@
 // RUN: %clang_cc1 %s -I%S -triple=x86_64-apple-darwin10 -std=c++98 -emit-llvm -o %t
 // RUN: %clang_cc1 %s -I%S -triple=x86_64-apple-darwin10 -std=c++98 -O2 -disable-llvm-passes -emit-llvm -o %t.opt
+// RUN: %clang_cc1 %s -I%S -triple=x86_64-apple-darwin10 -std=c++98 -O2 -disable-llvm-passes -emit-llvm -o %t.vtable -fforce-emit-vtables
 // RUN: FileCheck --check-prefix=CHECK-TEST1 %s < %t
 // RUN: FileCheck --check-prefix=CHECK-TEST2 %s < %t
 // RUN: FileCheck --check-prefix=CHECK-TEST5 %s < %t
@@ -13,10 +14,13 @@
 // RUN: FileCheck --check-prefix=CHECK-TEST15 %s < %t.opt
 // RUN: FileCheck --check-prefix=CHECK-TEST16 %s < %t.opt
 // RUN: FileCheck --check-prefix=CHECK-TEST17 %s < %t.opt
+// RUN: FileCheck --check-prefix=CHECK-FORCE-EMIT %s < %t.vtable
+
 
 #include 
 
 // CHECK-TEST1: @_ZTVN5Test11AE = external unnamed_addr constant
+// CHECK-FORCE-EMIT-DAG: @_ZTVN5Test11AE = available_externally unnamed_addr constant
 namespace Test1 {
 
 struct A {
@@ -213,14 +217,16 @@
 
 // because A's key function is defined here, vtable is generated in this TU
 // CHECK-TEST10-DAG: @_ZTVN6Test101AE = unnamed_addr constant
+// CHECK-FORCE-EMIT-DAG: @_ZTVN6Test101AE = unnamed_addr constant
 struct A {
   virtual void foo();
   virtual void bar();
 };
 void A::foo() {}
 
 // Because key function is inline we will generate vtable as linkonce_odr.
 // CHECK-TEST10-DAG: @_ZTVN6Test101DE = linkonce_odr unnamed_addr constant
+// CHECK-FORCE-EMIT-DAG: @_ZTVN6Test101DE = linkonce_odr unnamed_addr constant
 struct D : A {
   void bar();
 };
@@ -237,14 +243,17 @@
 // can't guarantee that we will be able to refer to bar from name
 // so (at the moment) we can't emit vtable available_externally.
 // CHECK-TEST10-DAG: @_ZTVN6Test101CE = external unnamed_addr constant
+// CHECK-FORCE-EMIT-DAG: @_ZTVN6Test101CE = available_externally unnamed_addr constant
 struct C : A {
   void bar() {}   // defined in body - not key function
   virtual inline void gar();  // inline in body - not key function
   virtual void car();
 };
 
 // no key function, vtable will be generated everywhere it will be used
 // CHECK-TEST10-DAG: @_ZTVN6Test101EE = linkonce_odr unnamed_addr constant
+// CHECK-FORCE-EMIT-DAG: @_ZTVN6Test101EE = linkonce_odr unnamed_addr constant
+
 struct E : A {};
 
 void g(A& a) {
@@ -298,11 +307,13 @@
 namespace Test12 {
 
 // CHECK-TEST12: @_ZTVN6Test121AE = external unnamed_addr constant
+// CHECK-FORCE-EMIT-DAG: @_ZTVN6Test121AE = available_externally unnamed_addr constant
 struct A {
   virtual void foo();
   virtual ~A() {}
 };
 // CHECK-TEST12: @_ZTVN6Test121BE = external unnamed_addr constant
+// CHECK-FORCE-EMIT-DAG: @_ZTVN6Test121BE = available_externally unnamed_addr constant
 struct B : A {
   void foo();
 };
@@ -319,6 +330,9 @@
 
 // CHECK-TEST13-DAG: @_ZTVN6Test131AE = available_externally unnamed_addr constant
 // CHECK-TEST13-DAG: @_ZTVN6Test131BE = external unnamed_addr constant
+// CHECK-FORCE-EMIT-DAG: @_ZTVN6Test131AE = available_externally unnamed_addr constant
+// CHECK-FORCE-EMIT-DAG: @_ZTVN6Test131BE = available_externally unnamed_addr constant
+
 struct A {
   virtual ~A();
 };
@@ -371,6 +385,8 @@
 // generate available_externally vtable for it.
 // CHECK-TEST16-DAG: @_ZTVN6Test161SE = external unnamed_addr constant
 // CHECK-TEST16-DAG: @_ZTVN6Test162S2E = available_externally
+// CHECK-FORCE-EMIT-DAG: @_ZTVN6Test161SE = external unnamed_addr constant
+// CHECK-FORCE-EMIT-DAG: @_ZTVN6Test162S2E = available_externally
 
 struct S {
   __attribute__((visibility("hidden"))) virtual void doStuff();
@@ -395,6 +411,10 @@
 // This test checks if we emit vtables opportunistically.
 // CHECK-TEST17-DAG: @_ZTVN6Test171AE = available_externally
 // CHECK-TEST17-DAG: @_ZTVN6Test171BE = external
+// CHECK-FORCE-EMIT-DAG: 

[PATCH] D47108: Add -fforce-emit-vtable

2018-05-19 Thread Piotr Padlewski via Phabricator via cfe-commits
Prazek created this revision.
Prazek added reviewers: rjmccall, rsmith, amharc, kuhar.
Herald added a subscriber: llvm-commits.

In many cases we can't devirtualize
because definition of vtable is not present. Most of the
time it is caused by inline virtual function not beeing
emitted. Forcing emitting of vtable adds a reference of these
inline virtual functions


Repository:
  rL LLVM

https://reviews.llvm.org/D47108

Files:
  clang/docs/ClangCommandLineReference.rst
  clang/docs/UsersManual.rst
  clang/include/clang/Driver/Options.td
  clang/include/clang/Frontend/CodeGenOptions.def
  clang/lib/CodeGen/ItaniumCXXABI.cpp
  clang/lib/Driver/ToolChains/Clang.cpp
  clang/lib/Frontend/CompilerInvocation.cpp
  clang/test/CodeGenCXX/vtable-available-externally.cpp
  clang/test/CodeGenCXX/vtable-linkage.cpp

Index: clang/test/CodeGenCXX/vtable-linkage.cpp
===
--- clang/test/CodeGenCXX/vtable-linkage.cpp
+++ clang/test/CodeGenCXX/vtable-linkage.cpp
@@ -1,11 +1,13 @@
 // RUN: %clang_cc1 %s -triple=x86_64-pc-linux -emit-llvm -o %t
 // RUN: %clang_cc1 %s -triple=x86_64-pc-linux -emit-llvm -std=c++03 -o %t.03
 // RUN: %clang_cc1 %s -triple=x86_64-pc-linux -emit-llvm -std=c++11 -o %t.11
+// RUN: %clang_cc1 %s -triple=x86_64-pc-linux -emit-llvm -std=c++11 -o %t.vtables -fforce-emit-vtables -O3
 // RUN: %clang_cc1 %s -triple=x86_64-apple-darwin10 -disable-llvm-passes -O3 -emit-llvm -o %t.opt
 // RUN: FileCheck %s < %t
 // RUN: FileCheck %s < %t.03
 // RUN: FileCheck %s < %t.11
 // RUN: FileCheck --check-prefix=CHECK-OPT %s < %t.opt
+// RUN: FileCheck --check-prefix=CHECK-OPT %s < %t.vtables
 
 namespace {
   struct A {
Index: clang/test/CodeGenCXX/vtable-available-externally.cpp
===
--- clang/test/CodeGenCXX/vtable-available-externally.cpp
+++ clang/test/CodeGenCXX/vtable-available-externally.cpp
@@ -1,5 +1,6 @@
 // RUN: %clang_cc1 %s -I%S -triple=x86_64-apple-darwin10 -std=c++98 -emit-llvm -o %t
 // RUN: %clang_cc1 %s -I%S -triple=x86_64-apple-darwin10 -std=c++98 -O2 -disable-llvm-passes -emit-llvm -o %t.opt
+// RUN: %clang_cc1 %s -I%S -triple=x86_64-apple-darwin10 -std=c++98 -O2 -disable-llvm-passes -emit-llvm -o %t.vtable -fforce-emit-vtables
 // RUN: FileCheck --check-prefix=CHECK-TEST1 %s < %t
 // RUN: FileCheck --check-prefix=CHECK-TEST2 %s < %t
 // RUN: FileCheck --check-prefix=CHECK-TEST5 %s < %t
@@ -13,10 +14,13 @@
 // RUN: FileCheck --check-prefix=CHECK-TEST15 %s < %t.opt
 // RUN: FileCheck --check-prefix=CHECK-TEST16 %s < %t.opt
 // RUN: FileCheck --check-prefix=CHECK-TEST17 %s < %t.opt
+// RUN: FileCheck --check-prefix=CHECK-FORCE-EMIT %s < %t.vtable
+
 
 #include 
 
 // CHECK-TEST1: @_ZTVN5Test11AE = external unnamed_addr constant
+// CHECK-FORCE-EMIT-DAG: @_ZTVN5Test11AE = available_externally unnamed_addr constant
 namespace Test1 {
 
 struct A {
@@ -213,14 +217,16 @@
 
 // because A's key function is defined here, vtable is generated in this TU
 // CHECK-TEST10-DAG: @_ZTVN6Test101AE = unnamed_addr constant
+// CHECK-FORCE-EMIT-DAG: @_ZTVN6Test101AE = unnamed_addr constant
 struct A {
   virtual void foo();
   virtual void bar();
 };
 void A::foo() {}
 
 // Because key function is inline we will generate vtable as linkonce_odr.
 // CHECK-TEST10-DAG: @_ZTVN6Test101DE = linkonce_odr unnamed_addr constant
+// CHECK-FORCE-EMIT-DAG: @_ZTVN6Test101DE = linkonce_odr unnamed_addr constant
 struct D : A {
   void bar();
 };
@@ -237,14 +243,17 @@
 // can't guarantee that we will be able to refer to bar from name
 // so (at the moment) we can't emit vtable available_externally.
 // CHECK-TEST10-DAG: @_ZTVN6Test101CE = external unnamed_addr constant
+// CHECK-FORCE-EMIT-DAG: @_ZTVN6Test101CE = available_externally unnamed_addr constant
 struct C : A {
   void bar() {}   // defined in body - not key function
   virtual inline void gar();  // inline in body - not key function
   virtual void car();
 };
 
 // no key function, vtable will be generated everywhere it will be used
 // CHECK-TEST10-DAG: @_ZTVN6Test101EE = linkonce_odr unnamed_addr constant
+// CHECK-FORCE-EMIT-DAG: @_ZTVN6Test101EE = linkonce_odr unnamed_addr constant
+
 struct E : A {};
 
 void g(A& a) {
@@ -298,11 +307,13 @@
 namespace Test12 {
 
 // CHECK-TEST12: @_ZTVN6Test121AE = external unnamed_addr constant
+// CHECK-FORCE-EMIT-DAG: @_ZTVN6Test121AE = available_externally unnamed_addr constant
 struct A {
   virtual void foo();
   virtual ~A() {}
 };
 // CHECK-TEST12: @_ZTVN6Test121BE = external unnamed_addr constant
+// CHECK-FORCE-EMIT-DAG: @_ZTVN6Test121BE = available_externally unnamed_addr constant
 struct B : A {
   void foo();
 };
@@ -319,6 +330,9 @@
 
 // CHECK-TEST13-DAG: @_ZTVN6Test131AE = available_externally unnamed_addr constant
 // CHECK-TEST13-DAG: @_ZTVN6Test131BE = external unnamed_addr constant
+// CHECK-FORCE-EMIT-DAG: @_ZTVN6Test131AE = available_externally unnamed_addr constant
+// 

[PATCH] D47090: Implement C++17 .

2018-05-19 Thread Eric Fiselier via Phabricator via cfe-commits
EricWF added inline comments.



Comment at: src/memory_resource.cpp:62
+
+namespace {
+

Quuxplusone wrote:
> EricWF wrote:
> > We certainly don't want a different definition of the global resources in 
> > each TU. See below.
> @EricWF: I think all of your comments in this file are the result of 
> misreading "src/memory_resource.cpp" as "include/memory_resource".  Or else I 
> *totally* don't understand the current directory organization and you're 
> going to have to instruct me. :)
> 
Woops. I feel dumb now. 


Repository:
  rCXX libc++

https://reviews.llvm.org/D47090



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


[PATCH] D47090: Implement C++17 .

2018-05-19 Thread Arthur O'Dwyer via Phabricator via cfe-commits
Quuxplusone added inline comments.



Comment at: include/__memory_resource_base:196
+  typename __uses_alloc_ctor<
+  _T1, polymorphic_allocator&, _Args1...
+  >::type()

>> (B) It's got different semantics around uses-allocator construction because 
>> of https://wg21.link/lwg2969
> Issue resolutions should probably be applied to the experimental versions as 
> well.

Okay, I can roll with that. I'll create a new patch that modifies 
``'s uses-allocator parts per LWG2969 (and my 
followup DR), without any other diffs.

Should `` continue caring about 
`std::experimental::erased_type`, which was in LFTS and LFTSv2 but did not make 
it into C++17?  My kneejerk reaction is "yes".  (And at the end of this 
process, when we copy `` into 
``, should `` care about `erased_type`? My 
kneejerk reaction is "no".)



Comment at: src/memory_resource.cpp:62
+
+namespace {
+

EricWF wrote:
> We certainly don't want a different definition of the global resources in 
> each TU. See below.
@EricWF: I think all of your comments in this file are the result of misreading 
"src/memory_resource.cpp" as "include/memory_resource".  Or else I *totally* 
don't understand the current directory organization and you're going to have to 
instruct me. :)



Repository:
  rCXX libc++

https://reviews.llvm.org/D47090



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


[PATCH] D46845: [libcxx][c++17] P0083R5: Splicing Maps and Sets

2018-05-19 Thread Erik Pilkington via Phabricator via cfe-commits
erik.pilkington added a comment.

In https://reviews.llvm.org/D46845#1098634, @rsmith wrote:

> One way we could deal with this is by adding an attribute to the compiler to 
> indicate "the const is a lie", that we can apply to `std::pair::first`, with 
> the semantics being that a top-level `const` is ignored when determining the 
> "real" type of the member (and so mutating the member after a `const_cast` 
> has defined behavior).  This would apply to //all// `std::pair`s, not just 
> the `node_handle` case, but in practice we don't optimize on the basis of a 
> member being declared `const` *anyway*, so this isn't such a big deal right 
> now.


Would you mind elaborating on this? If we don't optimize on a member being 
const, then what should this attribute actually do? The only thing I can think 
of is making a field with type `const T` with the attribute claim it's a `T` to 
TBAA, but that would be a no-op because loads and stores through those types 
are compatible anyways.

In https://reviews.llvm.org/D46845#1098634, @rsmith wrote:

> Yet another possibility would be to only ever access the `key` field through 
> a type annotated with `__attribute__((may_alias))`, and then launder the node 
> pointer when we're ready to insert it back into the container (to "pick up" 
> the new value of the const member). That's formally breaking the rules (a 
> `launder` isn't enough, because we didn't actually create a new object, and 
> in any case we still mutated the value of a `const` subobject), but it'll 
> probably work fine across compilers that support the attribute.


What about instead of type-punning between pair and pair 
(with may_alias) we just did a const_cast in key, and launder the pair when 
finished? Because loads and stores to `const K` and `K` are already assumed to 
alias each other, we should be able to omit the may_alias attribute (right?). 
Would that be enough to placate the compiler? If it is, then I think we should 
just do this and avoid adding another attribute to clang. I'll upload a patch 
with this to show what I mean.

Thanks! 
Erik


https://reviews.llvm.org/D46845



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


[libcxx] r332811 - Implement deduction guides for forward_list

2018-05-19 Thread Marshall Clow via cfe-commits
Author: marshall
Date: Sat May 19 09:02:05 2018
New Revision: 332811

URL: http://llvm.org/viewvc/llvm-project?rev=332811=rev
Log:
Implement deduction guides for forward_list

Added:

libcxx/trunk/test/std/containers/sequences/forwardlist/forwardlist.cons/deduct.fail.cpp

libcxx/trunk/test/std/containers/sequences/forwardlist/forwardlist.cons/deduct.pass.cpp
Modified:
libcxx/trunk/include/forward_list

Modified: libcxx/trunk/include/forward_list
URL: 
http://llvm.org/viewvc/llvm-project/libcxx/trunk/include/forward_list?rev=332811=332810=332811=diff
==
--- libcxx/trunk/include/forward_list (original)
+++ libcxx/trunk/include/forward_list Sat May 19 09:02:05 2018
@@ -134,6 +134,11 @@ public:
 void reverse() noexcept;
 };
 
+
+template ::value_type>>
+forward_list(InputIterator, InputIterator, Allocator = Allocator())
+-> forward_list::value_type, 
Allocator>;  // C++17
+
 template 
 bool operator==(const forward_list& x,
 const forward_list& y);
@@ -845,6 +850,23 @@ private:
 __sort(__node_pointer __f, difference_type __sz, _Compare& __comp);
 };
 
+
+#ifndef _LIBCPP_HAS_NO_DEDUCTION_GUIDES
+template::value_type>,
+ class = typename enable_if<__is_allocator<_Alloc>::value, void>::type
+ >
+forward_list(_InputIterator, _InputIterator)
+  -> forward_list::value_type, 
_Alloc>;
+
+template::value, void>::type
+ >
+forward_list(_InputIterator, _InputIterator, _Alloc)
+  -> forward_list::value_type, 
_Alloc>;
+#endif
+
 template 
 inline
 forward_list<_Tp, _Alloc>::forward_list(const allocator_type& __a)

Added: 
libcxx/trunk/test/std/containers/sequences/forwardlist/forwardlist.cons/deduct.fail.cpp
URL: 
http://llvm.org/viewvc/llvm-project/libcxx/trunk/test/std/containers/sequences/forwardlist/forwardlist.cons/deduct.fail.cpp?rev=332811=auto
==
--- 
libcxx/trunk/test/std/containers/sequences/forwardlist/forwardlist.cons/deduct.fail.cpp
 (added)
+++ 
libcxx/trunk/test/std/containers/sequences/forwardlist/forwardlist.cons/deduct.fail.cpp
 Sat May 19 09:02:05 2018
@@ -0,0 +1,42 @@
+//===--===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===--===//
+
+// 
+// UNSUPPORTED: c++98, c++03, c++11, c++14
+// UNSUPPORTED: libcpp-no-deduction-guides
+
+
+// template ::value_type>>
+//forward_list(InputIterator, InputIterator, Allocator = Allocator())
+//-> forward_list::value_type, 
Allocator>;
+//
+
+
+#include 
+#include 
+#include 
+#include 
+#include  // INT_MAX
+
+struct A {};
+
+int main()
+{  
+//  Test the explicit deduction guides
+
+//  Test the implicit deduction guides
+{
+//  forward_list (allocator &)
+std::forward_list fwl((std::allocator()));  // expected-error {{no 
viable constructor or deduction guide for deduction of template arguments of 
'forward_list'}}
+//  Note: The extra parens are necessary, since otherwise clang decides it is 
a function declaration.
+//  Also, we can't use {} instead of parens, because that constructs a
+//  forward_list>
+}
+
+}

Added: 
libcxx/trunk/test/std/containers/sequences/forwardlist/forwardlist.cons/deduct.pass.cpp
URL: 
http://llvm.org/viewvc/llvm-project/libcxx/trunk/test/std/containers/sequences/forwardlist/forwardlist.cons/deduct.pass.cpp?rev=332811=auto
==
--- 
libcxx/trunk/test/std/containers/sequences/forwardlist/forwardlist.cons/deduct.pass.cpp
 (added)
+++ 
libcxx/trunk/test/std/containers/sequences/forwardlist/forwardlist.cons/deduct.pass.cpp
 Sat May 19 09:02:05 2018
@@ -0,0 +1,103 @@
+//===--===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===--===//
+
+// 
+// UNSUPPORTED: c++98, c++03, c++11, c++14
+// UNSUPPORTED: libcpp-no-deduction-guides
+
+
+// template ::value_type>>
+//deque(InputIterator, InputIterator, Allocator = Allocator())
+//-> deque::value_type, Allocator>;
+//
+
+
+#include 
+#include 
+#include 
+#include 
+#include  // INT_MAX
+
+#include "test_macros.h"
+#include "test_iterators.h"
+#include "test_allocator.h"
+
+struct A {};
+
+int main()
+{
+  
+//  Test the explicit deduction guides
+{
+const int arr[] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9 };
+

r332806 - [Driver] Temporarily remove test for LLVM findNearest

2018-05-19 Thread Brian Gesiak via cfe-commits
Author: modocache
Date: Sat May 19 05:44:02 2018
New Revision: 332806

URL: http://llvm.org/viewvc/llvm-project?rev=332806=rev
Log:
[Driver] Temporarily remove test for LLVM findNearest

Summary:
This fixes a failure caused by the revert of https://reviews.llvm.org/rL332805.


Modified:
cfe/trunk/test/Driver/unknown-arg.c

Modified: cfe/trunk/test/Driver/unknown-arg.c
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Driver/unknown-arg.c?rev=332806=332805=332806=diff
==
--- cfe/trunk/test/Driver/unknown-arg.c (original)
+++ cfe/trunk/test/Driver/unknown-arg.c Sat May 19 05:44:02 2018
@@ -51,7 +51,6 @@
 // SILENT-NOT: warning:
 // CC1AS-DID-YOU-MEAN: error: unknown argument '-hell', did you mean '-help'?
 // CC1AS-DID-YOU-MEAN: error: unknown argument '--version', did you mean 
'-version'?
-// CC1AS-DID-YOU-MEAN: error: unknown argument '-debug-info-macros'
 // UNKNOWN-INTEGRATED: error: unknown integrated tool 'asphalt'. Valid tools 
include '-cc1' and '-cc1as'.
 
 // RUN: %clang -S %s -o %t.s  -Wunknown-to-clang-option 2>&1 | FileCheck 
--check-prefix=IGNORED %s


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


[PATCH] D47099: Disable casting of alloca for ActiveFlag

2018-05-19 Thread Yaxun Liu via Phabricator via cfe-commits
yaxunl added a comment.

In https://reviews.llvm.org/D47099#1105493, @rjmccall wrote:

> Maybe there should just be a method that makes a primitive alloca without the 
> casting, and then you can call that in CreateTempAlloca.


In many cases we still need to call CreateTempAlloca with cast enabled, since 
we are not certain there is only load from it and store to it. Any time it is 
stored to another memory location or passed to another function (e.g. 
constructor/destructor), it needs to be a pointer to  the language's default 
address space since the language sees it that way.


https://reviews.llvm.org/D47099



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


r332804 - [Driver] Loosen test for LLVM findNearest

2018-05-19 Thread Brian Gesiak via cfe-commits
Author: modocache
Date: Sat May 19 04:46:58 2018
New Revision: 332804

URL: http://llvm.org/viewvc/llvm-project?rev=332804=rev
Log:
[Driver] Loosen test for LLVM findNearest

Summary:
When https://reviews.llvm.org/D46776 landed to improve the behavior of
`llvm::OptTable::findNearest`, a PS4 buildbot began failing due to an
assertion that a suggestion "-debug-info-macro" should be provided for
the unrecognized option `clang -cc1as -debug-info-macros`. All other
buildbots succeeded in this check, and the PS4 buildbot succeeded in the
other `findNearest` tests.

Temporarily loosen this check in order to reland the `findNearest`
change.

Test Plan: check-clang


Modified:
cfe/trunk/test/Driver/unknown-arg.c

Modified: cfe/trunk/test/Driver/unknown-arg.c
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Driver/unknown-arg.c?rev=332804=332803=332804=diff
==
--- cfe/trunk/test/Driver/unknown-arg.c (original)
+++ cfe/trunk/test/Driver/unknown-arg.c Sat May 19 04:46:58 2018
@@ -51,7 +51,7 @@
 // SILENT-NOT: warning:
 // CC1AS-DID-YOU-MEAN: error: unknown argument '-hell', did you mean '-help'?
 // CC1AS-DID-YOU-MEAN: error: unknown argument '--version', did you mean 
'-version'?
-// CC1AS-DID-YOU-MEAN: error: unknown argument '-debug-info-macros', did you 
mean '-debug-info-macro'?
+// CC1AS-DID-YOU-MEAN: error: unknown argument '-debug-info-macros'
 // UNKNOWN-INTEGRATED: error: unknown integrated tool 'asphalt'. Valid tools 
include '-cc1' and '-cc1as'.
 
 // RUN: %clang -S %s -o %t.s  -Wunknown-to-clang-option 2>&1 | FileCheck 
--check-prefix=IGNORED %s


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


[PATCH] D47090: Implement C++17 .

2018-05-19 Thread Eric Fiselier via Phabricator via cfe-commits
EricWF added a subscriber: dexonsmith.
EricWF added a comment.






Comment at: src/memory_resource.cpp:62
+
+namespace {
+

We certainly don't want a different definition of the global resources in each 
TU. See below.



Comment at: src/memory_resource.cpp:64
+
+union ResourceInitHelper {
+  struct {

This should go inside the library, so we're not emitting an initializer in each 
TU.



Comment at: src/memory_resource.cpp:83
+
+memory_resource * new_delete_resource() _NOEXCEPT {
+return _init.resources.new_delete_res;

I think the global resources should be in the unversioned namespace `std::pmr` 
instead of `std::__v::pmr`. Like new/delete and exceptions I suspect we only 
want one definition of these in any given program. I'm considering every 
function from here up to and including `set_default_resource`.

@mclow.lists, @dexonsmith: what do you think?



Comment at: src/memory_resource.cpp:147
+
+template
+struct __mr_holder {

`_Tp`



Comment at: src/memory_resource.cpp:149
+struct __mr_holder {
+memory_resource *res;
+void *ptr;

`__res_`
`__ptr_`
`__size_`
`__align_`



Comment at: src/memory_resource.cpp:180
+struct __pool_resource_chunk {
+size_t bytes;
+size_t alignment;

`__bytes_`
`__alignment_` (or `__align_`)
`__allocation_`
`__next_`


Repository:
  rCXX libc++

https://reviews.llvm.org/D47090



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


[PATCH] D47070: [CUDA] Upgrade linked bitcode to enable inlining

2018-05-19 Thread Jonas Hahnfeld via Phabricator via cfe-commits
Hahnfeld added subscribers: chandlerc, ahatanak.
Hahnfeld added a comment.

Looks like this was added as a "temporary solution" in 
https://reviews.llvm.org/D8984. Meanwhile the attribute whitelist was merged 
half a year later (https://reviews.llvm.org/D7802), so maybe we can just get 
rid of comparing `target-cpu` and `target-features` entirely?


Repository:
  rC Clang

https://reviews.llvm.org/D47070



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


[PATCH] D47090: Implement C++17 .

2018-05-19 Thread Eric Fiselier via Phabricator via cfe-commits
EricWF added a comment.

I should add that this is the approach I've taken with 
`` with no complaints.


Repository:
  rCXX libc++

https://reviews.llvm.org/D47090



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


[PATCH] D47090: Implement C++17 .

2018-05-19 Thread Eric Fiselier via Phabricator via cfe-commits
EricWF added a comment.

In https://reviews.llvm.org/D47090#1105389, @Quuxplusone wrote:

> > I would prefer if we completed  (according to 
> > the current standard, not the LFTS spec), and then moved it.
> >  Would you be willing to do that instead?
>
> Let me see if I understand. libc++'s `` differs 
> from C++17 `` in at least these ways:
>  (A) It's missing `monotonic_buffer_resource` and 
> `{un,}synchronized_pool_resource`


Those were initially in the LFTS spec, I think they're in LFTS v2.

> (B) It's got different semantics around uses-allocator construction because 
> of https://wg21.link/lwg2969

Issue resolutions should probably be applied to the experimental versions as 
well.

> (C) It's got a different header name

I don't think this is relevant.

> This patch is basically proposing to fix things in the order C-A-B (and fix C 
> by making copies of everything); you're proposing to fix things in the order 
> A-B-C (and fix C by moving everything).
> 
> I have no objection to fixing A in `` if people 
> think that'd be useful. I didn't do that in this patch simply because I'd 
> observed other `` headers already getting replaced with 
> `#error` messages, and it seemed like any further work on the 
> `` headers would have been wasted.
> 
> I don't know who's using `` today, but in 
> theory I worry that fixing B in `` (before 
> doing C) might actually break someone's code.

I'm not concerned with it. We make no promises about ABI and API stability for 
 headers.  Do we implement the LFTS v1, v2, or in future, v3, 
API? I would rather follow the standard spec. I believe
it will actually make transitioning from `` to ``, since 
the behaviour is the same.


Repository:
  rCXX libc++

https://reviews.llvm.org/D47090



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