[PATCH] D49723: [OpenCL] Check for invalid kernel arguments in array types

2023-02-09 Thread Andrew Savonichev via Phabricator via cfe-commits
asavonic added a comment.

In D49723#4116435 , @Ayal wrote:

> This is admittedly a couple of years old by now, but wonder about that other 
> intended patch - Clang still seems to consider pointers in struct arguments 
> to be illegal in CL2.0 (and CL3.0) - please see 
> https://godbolt.org/z/E87z66h1d

Yeah, the patch got lost somewhere, I'm sorry...

TBH, I don't know why pointers in structs or arrays were disallowed in the 
first place. Even OpenCL 1.2 does not say it explicitly, although there is a 
bit suspicious point in s6.9.p:

  Arguments to kernel functions that are declared to be a struct or union do 
not allow
  OpenCL objects to be passed as elements of the struct or union

It does not say "pointers", just "OpenCL objects". Sounds more like events or 
images to me, not pointers.


Repository:
  rC Clang

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

https://reviews.llvm.org/D49723

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


[PATCH] D137154: Adding nvvm_reflect clang builtin

2022-11-01 Thread Andrew Savonichev via Phabricator via cfe-commits
asavonic added inline comments.



Comment at: llvm/include/llvm/IR/IntrinsicsNVVM.td:1581
 def int_nvvm_reflect :
-  Intrinsic<[llvm_i32_ty], [llvm_anyptr_ty], [IntrNoMem], "llvm.nvvm.reflect">;
+  Intrinsic<[llvm_i32_ty], [llvm_ptr_ty], [IntrNoMem], "llvm.nvvm.reflect">,
+  ClangBuiltin<"__nvvm_reflect">;

hdelan wrote:
> asavonic wrote:
> > What is there a reason to change the intrinsic?
> The clang builtin doesn't link up properly with the llvm intrinsic if 
> `llvm_anyptr_ty` is used. The `llvm_anyptr_ty` suggests to clang to find a 
> general `arg` parameter instead of an `Pointer` which results in a segfault. 
> Changing to `llvm_ptr_ty` fixes the issue
This sounds like a bug in clang. If clang's default lowering for builtins 
doesn't play well with `llvm_anyptr_ty`, it should be possible to implement it 
with custom lowering code ( in `CodeGenFunction::EmitNVPTXBuiltinExpr`) without 
changing the intrinsic. Some intrinsics with anyptr arguments are already 
implemented with custom lowering (LDG, some atomics).

Changing the intrinsic is problematic for backward compatibility. Overloaded 
intrinsic from old IR will not be recognized, pointers in non-zero address 
space cannot be used as arguments directly (must be addrspacecast to generic 
AS).


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D137154

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


[PATCH] D137154: Adding nvvm_reflect clang builtin

2022-11-01 Thread Andrew Savonichev via Phabricator via cfe-commits
asavonic added inline comments.



Comment at: llvm/include/llvm/IR/IntrinsicsNVVM.td:1581
 def int_nvvm_reflect :
-  Intrinsic<[llvm_i32_ty], [llvm_anyptr_ty], [IntrNoMem], "llvm.nvvm.reflect">;
+  Intrinsic<[llvm_i32_ty], [llvm_ptr_ty], [IntrNoMem], "llvm.nvvm.reflect">,
+  ClangBuiltin<"__nvvm_reflect">;

What is there a reason to change the intrinsic?



Comment at: llvm/lib/Target/NVPTX/NVVMReflect.cpp:123
 if (!Callee || (Callee->getName() != NVVM_REFLECT_FUNCTION &&
+Callee->getName() != NVVM_REFLECT_LLVM_INTRINSIC_NAME &&
 Callee->getIntrinsicID() != Intrinsic::nvvm_reflect))

This seems to be equivalent to `Callee->getIntrinsicID()` call below. Is there 
a case where the intrinsic is not recognized by `getIntrinsicID`?


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D137154

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


[PATCH] D125693: [DebugInfo][WIP] Support types, imports and static locals declared in a lexical block (3/5)

2022-05-18 Thread Andrew Savonichev via Phabricator via cfe-commits
asavonic added a comment.

Thanks a lot for the patch! It would be great to get this issue finally fixed. 
I assume that this is the main patch, other patches in the stack seem like just 
preparation/adjustments needed for this one to work.

> This an alternative implementation for D113741 
>  which relies on localDecls field of 
> DISubprogram or DILexicalBlock for getting local declarations (types, imports 
> or static variable) for a particular local scope.

Can you include a short description of the issue? PR19238 has a good and short 
example, we can inline it here.

> Another thing that should be noted that with this patch we will no longer 
> emit local declarations if its parent scope doesn't have a LexicalScope 
> calculated for it

If a local declaration (a type or a static variable) is optimized away, then 
with this patch we have no debug information for it, right? For types we have 
`-debug-info-kind=unused-types` as a workaround (as shown in 
lexical-block-retained-types.ll), so the issue is only with static variables 
that have no uses. Given that they were broken before this patch and there is 
no way to access them from a debugger (cannot set a breakpoint if a block is 
optimized away), I think it is fine.




Comment at: llvm/lib/CodeGen/AsmPrinter/DwarfDebug.cpp:1382
+  assert((!GV->getScope() || !isa(GV->getScope())) &&
+ "Unexpected function-local declaration!");
   if (Processed.insert(GV).second)

So here we discard LLVM IR metadata that have local declarations tied to a CU, 
right? This will break compatibility with old LLVM IR. Can we do some upgrade 
to convert this "old style" metadata the way we expect it now? Does it make 
sense to support both variants?


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D125693

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


[PATCH] D121299: [NVPTX] Disable DWARF .file directory for PTX

2022-04-26 Thread Andrew Savonichev via Phabricator via cfe-commits
This revision was not accepted when it landed; it landed in state "Needs 
Review".
This revision was landed with ongoing or failed builds.
This revision was automatically updated to reflect the committed changes.
Closed by commit rG0a27622a1d62: [NVPTX] Disable DWARF .file directory for PTX 
(authored by asavonic).

Changed prior to commit:
  https://reviews.llvm.org/D121299?vs=418011=425274#toc

Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D121299

Files:
  clang/lib/CodeGen/BackendUtil.cpp
  llvm/include/llvm/MC/MCAsmInfo.h
  llvm/include/llvm/MC/MCTargetOptions.h
  llvm/lib/CodeGen/LLVMTargetMachine.cpp
  llvm/lib/MC/MCTargetOptions.cpp
  llvm/lib/Target/NVPTX/MCTargetDesc/NVPTXMCAsmInfo.cpp
  llvm/test/DebugInfo/NVPTX/dbg-declare-alloca.ll
  llvm/test/DebugInfo/NVPTX/debug-file-loc-only.ll
  llvm/test/DebugInfo/NVPTX/debug-file-loc.ll
  llvm/test/DebugInfo/NVPTX/debug-loc-offset.ll
  llvm/test/DebugInfo/NVPTX/dwarf-file-dir.ll
  llvm/tools/llc/llc.cpp

Index: llvm/tools/llc/llc.cpp
===
--- llvm/tools/llc/llc.cpp
+++ llvm/tools/llc/llc.cpp
@@ -503,11 +503,22 @@
 TargetMachine::parseBinutilsVersion(BinutilsVersion);
 Options.DisableIntegratedAS = NoIntegratedAssembler;
 Options.MCOptions.ShowMCEncoding = ShowMCEncoding;
-Options.MCOptions.MCUseDwarfDirectory = DwarfDirectory;
 Options.MCOptions.AsmVerbose = AsmVerbose;
 Options.MCOptions.PreserveAsmComments = PreserveComments;
 Options.MCOptions.IASSearchPaths = IncludeDirs;
 Options.MCOptions.SplitDwarfFile = SplitDwarfFile;
+if (DwarfDirectory.getPosition()) {
+  Options.MCOptions.MCUseDwarfDirectory =
+  DwarfDirectory ? MCTargetOptions::EnableDwarfDirectory
+ : MCTargetOptions::DisableDwarfDirectory;
+} else {
+  // -dwarf-directory is not set explicitly. Some assemblers
+  // (e.g. GNU as or ptxas) do not support `.file directory'
+  // syntax prior to DWARFv5. Let the target decide the default
+  // value.
+  Options.MCOptions.MCUseDwarfDirectory =
+  MCTargetOptions::DefaultDwarfDirectory;
+}
   };
 
   Optional RM = codegen::getExplicitRelocModel();
Index: llvm/test/DebugInfo/NVPTX/dwarf-file-dir.ll
===
--- /dev/null
+++ llvm/test/DebugInfo/NVPTX/dwarf-file-dir.ll
@@ -0,0 +1,27 @@
+; RUN: llc < %s -mtriple=nvptx64-nvidia-cuda | FileCheck --check-prefix=CHECK-NODIR %s
+; RUN: llc < %s -mtriple=nvptx64-nvidia-cuda -dwarf-directory=1 | FileCheck --check-prefix=CHECK-DIR %s
+
+; CHECK-NODIR: .file   {{[0-9]+}} "/tmp/dbginfo/a/a.cpp"
+;
+; ptxas does not support .file directory syntax, but it can still be
+; forced by -dwarf-directory=1
+; CHECK-DIR:   .file   {{[0-9]+}} "/tmp/dbginfo/a" "a.cpp"
+
+define void @_Z4funcv() !dbg !4 {
+entry:
+  ret void, !dbg !5
+}
+
+!llvm.dbg.cu = !{!0}
+!llvm.module.flags = !{!8, !9}
+
+!0 = distinct !DICompileUnit(language: DW_LANG_C_plus_plus, producer: "clang version 3.5.0 ", isOptimized: false, emissionKind: FullDebug, file: !1, enums: !2, retainedTypes: !2, globals: !2, imports: !2)
+!1 = !DIFile(filename: "a.cpp", directory: "/tmp/dbginfo/a")
+!2 = !{}
+!4 = distinct !DISubprogram(name: "func", linkageName: "_Z4funcv", line: 1, isLocal: false, isDefinition: true, virtualIndex: 6, flags: DIFlagPrototyped, isOptimized: false, unit: !0, scopeLine: 1, file: !1, scope: !1, type: !6, retainedNodes: !2)
+!5 = !DILocation(line: 2, scope: !4)
+!6 = !DISubroutineType(types: !7)
+!7 = !{null}
+!8 = !{i32 2, !"Dwarf Version", i32 4}
+!9 = !{i32 1, !"Debug Info Version", i32 3}
+
Index: llvm/test/DebugInfo/NVPTX/debug-loc-offset.ll
===
--- llvm/test/DebugInfo/NVPTX/debug-loc-offset.ll
+++ llvm/test/DebugInfo/NVPTX/debug-loc-offset.ll
@@ -1,4 +1,4 @@
-; RUN: llc -mtriple=nvptx64-nvidia-cuda -dwarf-directory=0 < %s | FileCheck %s
+; RUN: llc -mtriple=nvptx64-nvidia-cuda < %s | FileCheck %s
 
 ; CHECK: .target sm_{{[0-9]+}}, debug
 
Index: llvm/test/DebugInfo/NVPTX/debug-file-loc.ll
===
--- llvm/test/DebugInfo/NVPTX/debug-file-loc.ll
+++ llvm/test/DebugInfo/NVPTX/debug-file-loc.ll
@@ -27,8 +27,8 @@
   ret void, !dbg !11
 }
 
-; CHECK-DAG: .file [[FOO]] "{{.*}}foo.h"
-; CHECK-DAG: .file [[BAR]] "{{.*}}bar.cu"
+; CHECK-DAG: .file [[FOO]] "/source/dir/foo.h"
+; CHECK-DAG: .file [[BAR]] "/source/dir/bar.cu"
 ; CHECK: .section .debug_abbrev
 ; CHECK-NEXT: {
 ; CHECK-NEXT: .b8 1// Abbreviation Code
Index: llvm/test/DebugInfo/NVPTX/debug-file-loc-only.ll
===
--- llvm/test/DebugInfo/NVPTX/debug-file-loc-only.ll
+++ llvm/test/DebugInfo/NVPTX/debug-file-loc-only.ll
@@ -27,8 +27,8 @@
   ret void, 

[PATCH] D121299: [NVPTX] Disable DWARF .file directory for PTX

2022-04-25 Thread Andrew Savonichev via Phabricator via cfe-commits
asavonic added a comment.

I'm going to merge the patch in a couple of days, unless anyone has a strong 
opinion against it.
Alternative options:

- revert this default back to false (not great for other targets)
- add a check for `Triple == NVPTX` directly to llc (tools other than llc will 
have to replicate the same logic)


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D121299

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


[PATCH] D121299: [NVPTX] Disable DWARF .file directory for PTX

2022-04-20 Thread Andrew Savonichev via Phabricator via cfe-commits
asavonic added a comment.
Herald added a subscriber: mattd.

ping


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D121299

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


[PATCH] D121299: [NVPTX] Disable DWARF .file directory for PTX

2022-04-14 Thread Andrew Savonichev via Phabricator via cfe-commits
asavonic added a comment.
Herald added a subscriber: gchakrabarti.

@MaskRay, should we merge this patch or rework it?


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D121299

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


[PATCH] D121299: [NVPTX] Disable DWARF .file directory for PTX

2022-03-24 Thread Andrew Savonichev via Phabricator via cfe-commits
asavonic updated this revision to Diff 418011.
asavonic added a comment.
Herald added a project: clang.
Herald added a subscriber: cfe-commits.

- Fixed Clang build.


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D121299

Files:
  clang/lib/CodeGen/BackendUtil.cpp
  llvm/include/llvm/MC/MCAsmInfo.h
  llvm/include/llvm/MC/MCTargetOptions.h
  llvm/lib/CodeGen/LLVMTargetMachine.cpp
  llvm/lib/MC/MCTargetOptions.cpp
  llvm/lib/Target/NVPTX/MCTargetDesc/NVPTXMCAsmInfo.cpp
  llvm/test/DebugInfo/NVPTX/dbg-declare-alloca.ll
  llvm/test/DebugInfo/NVPTX/debug-file-loc-only.ll
  llvm/test/DebugInfo/NVPTX/debug-file-loc.ll
  llvm/test/DebugInfo/NVPTX/debug-loc-offset.ll
  llvm/test/DebugInfo/NVPTX/dwarf-file-dir.ll
  llvm/tools/llc/llc.cpp

Index: llvm/tools/llc/llc.cpp
===
--- llvm/tools/llc/llc.cpp
+++ llvm/tools/llc/llc.cpp
@@ -502,11 +502,22 @@
 TargetMachine::parseBinutilsVersion(BinutilsVersion);
 Options.DisableIntegratedAS = NoIntegratedAssembler;
 Options.MCOptions.ShowMCEncoding = ShowMCEncoding;
-Options.MCOptions.MCUseDwarfDirectory = DwarfDirectory;
 Options.MCOptions.AsmVerbose = AsmVerbose;
 Options.MCOptions.PreserveAsmComments = PreserveComments;
 Options.MCOptions.IASSearchPaths = IncludeDirs;
 Options.MCOptions.SplitDwarfFile = SplitDwarfFile;
+if (DwarfDirectory.getPosition()) {
+  Options.MCOptions.MCUseDwarfDirectory =
+  DwarfDirectory ? MCTargetOptions::EnableDwarfDirectory
+ : MCTargetOptions::DisableDwarfDirectory;
+} else {
+  // -dwarf-directory is not set explicitly. Some assemblers
+  // (e.g. GNU as or ptxas) do not support `.file directory'
+  // syntax prior to DWARFv5. Let the target decide the default
+  // value.
+  Options.MCOptions.MCUseDwarfDirectory =
+  MCTargetOptions::DefaultDwarfDirectory;
+}
   };
 
   Optional RM = codegen::getExplicitRelocModel();
Index: llvm/test/DebugInfo/NVPTX/dwarf-file-dir.ll
===
--- /dev/null
+++ llvm/test/DebugInfo/NVPTX/dwarf-file-dir.ll
@@ -0,0 +1,27 @@
+; RUN: llc < %s -mtriple=nvptx64-nvidia-cuda | FileCheck --check-prefix=CHECK-NODIR %s
+; RUN: llc < %s -mtriple=nvptx64-nvidia-cuda -dwarf-directory=1 | FileCheck --check-prefix=CHECK-DIR %s
+
+; CHECK-NODIR: .file   {{[0-9]+}} "/tmp/dbginfo/a/a.cpp"
+;
+; ptxas does not support .file directory syntax, but it can still be
+; forced by -dwarf-directory=1
+; CHECK-DIR:   .file   {{[0-9]+}} "/tmp/dbginfo/a" "a.cpp"
+
+define void @_Z4funcv() !dbg !4 {
+entry:
+  ret void, !dbg !5
+}
+
+!llvm.dbg.cu = !{!0}
+!llvm.module.flags = !{!8, !9}
+
+!0 = distinct !DICompileUnit(language: DW_LANG_C_plus_plus, producer: "clang version 3.5.0 ", isOptimized: false, emissionKind: FullDebug, file: !1, enums: !2, retainedTypes: !2, globals: !2, imports: !2)
+!1 = !DIFile(filename: "a.cpp", directory: "/tmp/dbginfo/a")
+!2 = !{}
+!4 = distinct !DISubprogram(name: "func", linkageName: "_Z4funcv", line: 1, isLocal: false, isDefinition: true, virtualIndex: 6, flags: DIFlagPrototyped, isOptimized: false, unit: !0, scopeLine: 1, file: !1, scope: !1, type: !6, retainedNodes: !2)
+!5 = !DILocation(line: 2, scope: !4)
+!6 = !DISubroutineType(types: !7)
+!7 = !{null}
+!8 = !{i32 2, !"Dwarf Version", i32 4}
+!9 = !{i32 1, !"Debug Info Version", i32 3}
+
Index: llvm/test/DebugInfo/NVPTX/debug-loc-offset.ll
===
--- llvm/test/DebugInfo/NVPTX/debug-loc-offset.ll
+++ llvm/test/DebugInfo/NVPTX/debug-loc-offset.ll
@@ -1,4 +1,4 @@
-; RUN: llc -mtriple=nvptx64-nvidia-cuda -dwarf-directory=0 < %s | FileCheck %s
+; RUN: llc -mtriple=nvptx64-nvidia-cuda < %s | FileCheck %s
 
 ; CHECK: .target sm_{{[0-9]+}}, debug
 
Index: llvm/test/DebugInfo/NVPTX/debug-file-loc.ll
===
--- llvm/test/DebugInfo/NVPTX/debug-file-loc.ll
+++ llvm/test/DebugInfo/NVPTX/debug-file-loc.ll
@@ -27,8 +27,8 @@
   ret void, !dbg !11
 }
 
-; CHECK-DAG: .file [[FOO]] "{{.*}}foo.h"
-; CHECK-DAG: .file [[BAR]] "{{.*}}bar.cu"
+; CHECK-DAG: .file [[FOO]] "/source/dir/foo.h"
+; CHECK-DAG: .file [[BAR]] "/source/dir/bar.cu"
 ; CHECK: .section .debug_abbrev
 ; CHECK-NEXT: {
 ; CHECK-NEXT: .b8 1// Abbreviation Code
Index: llvm/test/DebugInfo/NVPTX/debug-file-loc-only.ll
===
--- llvm/test/DebugInfo/NVPTX/debug-file-loc-only.ll
+++ llvm/test/DebugInfo/NVPTX/debug-file-loc-only.ll
@@ -27,8 +27,8 @@
   ret void, !dbg !11
 }
 
-; CHECK-DAG: .file [[FOO]] "{{.*}}foo.h"
-; CHECK-DAG: .file [[BAR]] "{{.*}}bar.cu"
+; CHECK-DAG: .file [[FOO]] "/source/dir/foo.h"
+; CHECK-DAG: .file [[BAR]] "/source/dir/bar.cu"
 
 ; CHECK-NOT: .section 

[PATCH] D114782: [X86][clang] Emit diagnostic for float and double when we have features -x87 and -sse on 64-bits

2021-12-07 Thread Andrew Savonichev via Phabricator via cfe-commits
asavonic accepted this revision.
asavonic added a comment.
This revision is now accepted and ready to land.

LGTM. The new diagnostic is not generic, but it is probably fine as long as 
x86_64 is the only target that needs this.


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D114782

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


[PATCH] D114162: [X86][clang] Enable floating-point type for -mno-x87 option on 32-bits

2021-11-29 Thread Andrew Savonichev via Phabricator via cfe-commits
asavonic accepted this revision.
asavonic added a comment.
This revision is now accepted and ready to land.

LGTM. We can also remove all code related to HasFPReturn, it is no longer 
needed.


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D114162

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


[PATCH] D114162: [X86][clang] Enable floating-point type for -mno-x87 option on 32-bits

2021-11-19 Thread Andrew Savonichev via Phabricator via cfe-commits
asavonic added inline comments.



Comment at: clang/lib/Basic/Targets/X86.cpp:385
 
-  if (!HasX87) {
-if (LongDoubleFormat == ::APFloat::x87DoubleExtended())
-  HasLongDouble = false;
-if (getTriple().getArch() == llvm::Triple::x86)
-  HasFPReturn = false;
-  }
+  if (!HasX87 && getTriple().getArch() == llvm::Triple::x86_64 &&
+  LongDoubleFormat == ::APFloat::x87DoubleExtended())

pengfei wrote:
> asavonic wrote:
> > I see that D112143 changed the ABI so that FP return values do not use x87 
> > registers on i386. Therefore HasFPReturn flag can be removed.
> > 
> > However, operations with long double (x87 80-bit) should still be 
> > unsupported on both targets, because IIRC there is no SSE equivalent for 
> > them. GCC compiles them as soft-fp when -mno-x87 is set, but I haven't 
> > found 80-bit soft-fp implementation in LLVM.
> > ```
> > long double baz(long double a, long double b) {
> > return a + b;
> > }
> > ```
> > 
> > ```
> > baz:
> >[...]
> >call  __addxf3
> > ```
> > For some reason GCC only does this for for i386 target, for x86_64 it just 
> > emits the diagnostic about disabled x87.
> Thanks for looking at this patch.
> I don't think we need to exclude f80 particularly. IIUC, backend tries all 
> possible ways to lower a given operation. Lowering to library is always the 
> last choice. So the behavior is not confined to soft-fp.
> It's true LLVM has problems with f80 lowering without x87. I commented it in 
> D112143 and hope D100091 will fix them. We don't need to bother to change it 
> again in future.
> 
> > For some reason GCC only does this for for i386 target, for x86_64 it just 
> > emits the diagnostic about disabled x87.
> I think the root reason is the difference in ABI. 32-bits ABI allows passing 
> and returning f80 without x87 registers while 64-bits doesn't. So we have to 
> and only need to disable it for x86_64.
> I don't think we need to exclude f80 particularly. IIUC, backend tries all 
> possible ways to lower a given operation. Lowering to library is always the 
> last choice. So the behavior is not confined to soft-fp.
> It's true LLVM has problems with f80 lowering without x87. I commented it in 
> D112143 and hope D100091 will fix them. We don't need to bother to change it 
> again in future.

Right, but can LLVM lower any x87 80-bit fp operations other than return values?
If it cannot, then I think a source level diagnostic is a good thing to have. 
Otherwise the only handling we have is the codegen crash with "x87 register 
return with x87 disabled" and no source-level context.


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D114162

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


[PATCH] D114162: [X86][clang] Enable floating-point type for -mno-x87 option on 32-bits

2021-11-19 Thread Andrew Savonichev via Phabricator via cfe-commits
asavonic added inline comments.



Comment at: clang/lib/Basic/Targets/X86.cpp:385
 
-  if (!HasX87) {
-if (LongDoubleFormat == ::APFloat::x87DoubleExtended())
-  HasLongDouble = false;
-if (getTriple().getArch() == llvm::Triple::x86)
-  HasFPReturn = false;
-  }
+  if (!HasX87 && getTriple().getArch() == llvm::Triple::x86_64 &&
+  LongDoubleFormat == ::APFloat::x87DoubleExtended())

I see that D112143 changed the ABI so that FP return values do not use x87 
registers on i386. Therefore HasFPReturn flag can be removed.

However, operations with long double (x87 80-bit) should still be unsupported 
on both targets, because IIRC there is no SSE equivalent for them. GCC compiles 
them as soft-fp when -mno-x87 is set, but I haven't found 80-bit soft-fp 
implementation in LLVM.
```
long double baz(long double a, long double b) {
return a + b;
}
```

```
baz:
   [...]
   call  __addxf3
```
For some reason GCC only does this for for i386 target, for x86_64 it just 
emits the diagnostic about disabled x87.


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D114162

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


[PATCH] D98895: [X86][clang] Disable long double type for -mno-x87 option

2021-11-09 Thread Andrew Savonichev via Phabricator via cfe-commits
asavonic added a comment.

> @asavonic I spoke offline with @erichkeane. I was mistaken. There are only 2 
> error diagnostics generated (upstream) after this patch. The additional 
> diagnostic generated at `bar ` after your patch is correct. We just need to 
> remove the third diagnostic downstream. So nothing needs to be done here. I 
> apologize for the confusion and trouble.

No worries. Thanks a lot for checking this.


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D98895

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


[PATCH] D98895: [X86][clang] Disable long double type for -mno-x87 option

2021-11-09 Thread Andrew Savonichev via Phabricator via cfe-commits
asavonic added a comment.

In D98895#3119064 , @erichkeane wrote:

> In D98895#3119027 , @asavonic wrote:
>
>> In D98895#3118821 , @eandrews wrote:
>>
>>> This patch causes a regression.
>>>
>>> To reproduce - `clang -cc1 -fsycl-is-device -triple spir64 test.cpp`
>>>
>>>   test.cpp:x:3: error: 'bar<__float128>' requires 128 bit size '__float128' 
>>> type support, but target 'spir64' does not support it
>>>   T bar() { return T(); };
>>> ^
>>>
>>> I looked at it briefly, and I believe the issue is call to 
>>> `checkTypeSupport()` in `ActOnFinishFunctionBody()`. I tried deleting the 
>>> call but it breaks tests (E.g. L26 in x86_64-no-x87.cpp). @asavonic Please 
>>> take a look. I will be reverting the patch if this cannot be fixed soon.
>>
>> The diagnostic seems to be correct - this instance of `bar` returns an 
>> unsupported type. Why do you think it should not be diagnosed?
>
> I believe the problem is that there are now _3_ different diagnostics for the 
> same thing, the one on 'bar', plus 2 more here:
>
> `auto malAutoTemp5 = bar<__float128>();`
>
> I think i would expect 1 error on 'bar', 1 error on the deduced 'auto', but 
> the 3rd is superfluous.

I will check if there is a way to filter it out. However, I don't think that it 
is a good reason to revert the patch.


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D98895

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


[PATCH] D98895: [X86][clang] Disable long double type for -mno-x87 option

2021-11-09 Thread Andrew Savonichev via Phabricator via cfe-commits
asavonic added a comment.

In D98895#3118821 , @eandrews wrote:

> This patch causes a regression.
>
> To reproduce - `clang -cc1 -fsycl-is-device -triple spir64 test.cpp`
>
>   test.cpp:x:3: error: 'bar<__float128>' requires 128 bit size '__float128' 
> type support, but target 'spir64' does not support it
>   T bar() { return T(); };
> ^
>
> I looked at it briefly, and I believe the issue is call to 
> `checkTypeSupport()` in `ActOnFinishFunctionBody()`. I tried deleting the 
> call but it breaks tests (E.g. L26 in x86_64-no-x87.cpp). @asavonic Please 
> take a look. I will be reverting the patch if this cannot be fixed soon.

The diagnostic seems to be correct - this instance of `bar` returns an 
unsupported type. Why do you think it should not be diagnosed?


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D98895

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


[PATCH] D98895: [X86][clang] Disable long double type for -mno-x87 option

2021-11-04 Thread Andrew Savonichev via Phabricator via cfe-commits
asavonic added a comment.

@nickdesaulniers, thanks a lot for reporting this!
Unfortunately it is not easy to keep compatibility with GCC in this case. GCC 
has this diagnostic very late in the pipeline, and trivial uses of `long 
double` type (e.g. unused variables, constant expressions) can be optimized 
away before that. We cannot do the same with LLVM, because there is no way to 
emit a nice source-level diagnostic from the codegen.
I suggest to fix the kernel, because it looks like the `long double` literal is 
not intentional and can be replaced with just `double`.


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D98895

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


[PATCH] D98895: [X86][clang] Disable long double type for -mno-x87 option

2021-11-03 Thread Andrew Savonichev via Phabricator via cfe-commits
This revision was landed with ongoing or failed builds.
This revision was automatically updated to reflect the committed changes.
Closed by commit rGa8083d42b1c3: [X86][clang] Disable long double type for 
-mno-x87 option (authored by asavonic).

Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D98895

Files:
  clang/include/clang/Basic/DiagnosticSemaKinds.td
  clang/include/clang/Basic/TargetInfo.h
  clang/lib/Basic/TargetInfo.cpp
  clang/lib/Basic/Targets/X86.cpp
  clang/lib/Basic/Targets/X86.h
  clang/lib/Sema/Sema.cpp
  clang/lib/Sema/SemaDecl.cpp
  clang/test/Sema/x86-no-x87.cpp
  clang/test/Sema/x86_64-no-x87.cpp
  clang/test/SemaSYCL/float128.cpp

Index: clang/test/SemaSYCL/float128.cpp
===
--- clang/test/SemaSYCL/float128.cpp
+++ clang/test/SemaSYCL/float128.cpp
@@ -22,6 +22,8 @@
   C.field1 = A;
 }
 
+long double ld_func(long double arg);
+
 void usage() {
   // expected-note@+1 3{{'A' defined here}}
   __float128 A;
@@ -48,6 +50,9 @@
 float F2 = 0.1f;
 // expected-error@+1 3{{expression requires 128 bit size '__float128' type support, but target 'spir64' does not support it}}
 float F3 = ((__float128)F1 * (__float128)F2) / 2.0f;
+
+// assume that long double is supported
+float F4 = ld_func(F3);
   };
 
   // expected-note@+1 {{called by 'usage'}}
Index: clang/test/Sema/x86_64-no-x87.cpp
===
--- /dev/null
+++ clang/test/Sema/x86_64-no-x87.cpp
@@ -0,0 +1,145 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s -triple x86_64-linux-gnu -target-feature -x87
+// RUN: %clang_cc1 -fsyntax-only -verify %s -triple x86_64-linux-gnu -DNOERROR
+
+#ifdef NOERROR
+// expected-no-diagnostics
+#endif
+
+typedef long double long_double;
+
+// Declaration is fine, unless it is called or defined.
+double decl(long_double x, long_double y);
+
+template 
+T decl_ld_del(T);
+
+// No code is generated for deleted functions
+long_double decl_ld_del(long_double) = delete;
+double decl_ld_del(double) = delete;
+float decl_ld_del(float) = delete;
+
+#ifndef NOERROR
+// expected-error@+4{{'def' requires  'long_double' (aka 'long double') type support, but target 'x86_64-unknown-linux-gnu' does not support it}}
+// expected-note@+3{{'def' defined here}}
+// expected-note@+2{{'x' defined here}}
+#endif
+int def(long_double x) {
+#ifndef NOERROR
+// expected-error@+2{{'x' requires  'long_double' (aka 'long double') type support, but target 'x86_64-unknown-linux-gnu' does not support it}}
+#endif
+  return (int)x;
+}
+
+#ifndef NOERROR
+// expected-note@+3{{'ld_args' defined here}}
+// expected-note@+2{{'ld_args' defined here}}
+#endif
+int ld_args(long_double x, long_double y);
+
+int call1(float x, float y) {
+#ifndef NOERROR
+  // expected-error@+2 2{{'ld_args' requires  'long_double' (aka 'long double') type support, but target 'x86_64-unknown-linux-gnu' does not support it}}
+#endif
+  return ld_args(x, y);
+}
+
+#ifndef NOERROR
+// expected-note@+2{{'ld_ret' defined here}}
+#endif
+long_double ld_ret(double x, double y);
+
+int call2(float x, float y) {
+#ifndef NOERROR
+  // expected-error@+2{{'ld_ret' requires  'long_double' (aka 'long double') type support, but target 'x86_64-unknown-linux-gnu' does not support it}}
+#endif
+  return (int)ld_ret(x, y);
+}
+
+int binop(double x, double y) {
+#ifndef NOERROR
+  // expected-error@+2 2{{expression requires  'long_double' (aka 'long double') type support, but target 'x86_64-unknown-linux-gnu' does not support it}}
+#endif
+  double z = (long_double)x * (long_double)y;
+  return (int)z;
+}
+
+void assign1(long_double *ret, double x) {
+#ifndef NOERROR
+  // expected-error@+2{{expression requires  'long_double' (aka 'long double') type support, but target 'x86_64-unknown-linux-gnu' does not support it}}
+#endif
+  *ret = x;
+}
+
+struct st_long_double1 {
+#ifndef NOERROR
+  // expected-note@+2{{'ld' defined here}}
+#endif
+  long_double ld;
+};
+
+struct st_long_double2 {
+#ifndef NOERROR
+  // expected-note@+2{{'ld' defined here}}
+#endif
+  long_double ld;
+};
+
+struct st_long_double3 {
+#ifndef NOERROR
+  // expected-note@+2{{'ld' defined here}}
+#endif
+  long_double ld;
+};
+
+void assign2() {
+  struct st_long_double1 st;
+#ifndef NOERROR
+  // expected-error@+3{{expression requires  'long_double' (aka 'long double') type support, but target 'x86_64-unknown-linux-gnu' does not support it}}
+  // expected-error@+2{{'ld' requires  'long_double' (aka 'long double') type support, but target 'x86_64-unknown-linux-gnu' does not support it}}
+#endif
+  st.ld = 0.42;
+}
+
+void assign3() {
+  struct st_long_double2 st;
+#ifndef NOERROR
+  // expected-error@+3{{expression requires  'long_double' (aka 'long double') type support, but target 'x86_64-unknown-linux-gnu' does not support it}}
+  // expected-error@+2{{'ld' requires  'long_double' (aka 'long 

[PATCH] D98895: [X86][clang] Disable long double type for -mno-x87 option

2021-11-01 Thread Andrew Savonichev via Phabricator via cfe-commits
asavonic updated this revision to Diff 383794.
asavonic added a comment.

- Added a test for SYCL.
- Excluded functions marked with C++ `delete` from the check.
- Moved the check function from `ActOnFunctionDeclarator` to 
`ActOnFinishFunctionBody`, because the deleted/defaulted property is not yet 
available in `ActOnFunctionDeclarator`.


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D98895

Files:
  clang/include/clang/Basic/DiagnosticSemaKinds.td
  clang/include/clang/Basic/TargetInfo.h
  clang/lib/Basic/TargetInfo.cpp
  clang/lib/Basic/Targets/X86.cpp
  clang/lib/Basic/Targets/X86.h
  clang/lib/Sema/Sema.cpp
  clang/lib/Sema/SemaDecl.cpp
  clang/test/Sema/x86-no-x87.cpp
  clang/test/Sema/x86_64-no-x87.cpp
  clang/test/SemaSYCL/float128.cpp

Index: clang/test/SemaSYCL/float128.cpp
===
--- clang/test/SemaSYCL/float128.cpp
+++ clang/test/SemaSYCL/float128.cpp
@@ -22,6 +22,8 @@
   C.field1 = A;
 }
 
+long double ld_func(long double arg);
+
 void usage() {
   // expected-note@+1 3{{'A' defined here}}
   __float128 A;
@@ -48,6 +50,9 @@
 float F2 = 0.1f;
 // expected-error@+1 3{{expression requires 128 bit size '__float128' type support, but target 'spir64' does not support it}}
 float F3 = ((__float128)F1 * (__float128)F2) / 2.0f;
+
+// assume that long double is supported
+float F4 = ld_func(F3);
   };
 
   // expected-note@+1 {{called by 'usage'}}
Index: clang/test/Sema/x86_64-no-x87.cpp
===
--- /dev/null
+++ clang/test/Sema/x86_64-no-x87.cpp
@@ -0,0 +1,145 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s -triple x86_64-linux-gnu -target-feature -x87
+// RUN: %clang_cc1 -fsyntax-only -verify %s -triple x86_64-linux-gnu -DNOERROR
+
+#ifdef NOERROR
+// expected-no-diagnostics
+#endif
+
+typedef long double long_double;
+
+// Declaration is fine, unless it is called or defined.
+double decl(long_double x, long_double y);
+
+template 
+T decl_ld_del(T);
+
+// No code is generated for deleted functions
+long_double decl_ld_del(long_double) = delete;
+double decl_ld_del(double) = delete;
+float decl_ld_del(float) = delete;
+
+#ifndef NOERROR
+// expected-error@+4{{'def' requires  'long_double' (aka 'long double') type support, but target 'x86_64-unknown-linux-gnu' does not support it}}
+// expected-note@+3{{'def' defined here}}
+// expected-note@+2{{'x' defined here}}
+#endif
+int def(long_double x) {
+#ifndef NOERROR
+// expected-error@+2{{'x' requires  'long_double' (aka 'long double') type support, but target 'x86_64-unknown-linux-gnu' does not support it}}
+#endif
+  return (int)x;
+}
+
+#ifndef NOERROR
+// expected-note@+3{{'ld_args' defined here}}
+// expected-note@+2{{'ld_args' defined here}}
+#endif
+int ld_args(long_double x, long_double y);
+
+int call1(float x, float y) {
+#ifndef NOERROR
+  // expected-error@+2 2{{'ld_args' requires  'long_double' (aka 'long double') type support, but target 'x86_64-unknown-linux-gnu' does not support it}}
+#endif
+  return ld_args(x, y);
+}
+
+#ifndef NOERROR
+// expected-note@+2{{'ld_ret' defined here}}
+#endif
+long_double ld_ret(double x, double y);
+
+int call2(float x, float y) {
+#ifndef NOERROR
+  // expected-error@+2{{'ld_ret' requires  'long_double' (aka 'long double') type support, but target 'x86_64-unknown-linux-gnu' does not support it}}
+#endif
+  return (int)ld_ret(x, y);
+}
+
+int binop(double x, double y) {
+#ifndef NOERROR
+  // expected-error@+2 2{{expression requires  'long_double' (aka 'long double') type support, but target 'x86_64-unknown-linux-gnu' does not support it}}
+#endif
+  double z = (long_double)x * (long_double)y;
+  return (int)z;
+}
+
+void assign1(long_double *ret, double x) {
+#ifndef NOERROR
+  // expected-error@+2{{expression requires  'long_double' (aka 'long double') type support, but target 'x86_64-unknown-linux-gnu' does not support it}}
+#endif
+  *ret = x;
+}
+
+struct st_long_double1 {
+#ifndef NOERROR
+  // expected-note@+2{{'ld' defined here}}
+#endif
+  long_double ld;
+};
+
+struct st_long_double2 {
+#ifndef NOERROR
+  // expected-note@+2{{'ld' defined here}}
+#endif
+  long_double ld;
+};
+
+struct st_long_double3 {
+#ifndef NOERROR
+  // expected-note@+2{{'ld' defined here}}
+#endif
+  long_double ld;
+};
+
+void assign2() {
+  struct st_long_double1 st;
+#ifndef NOERROR
+  // expected-error@+3{{expression requires  'long_double' (aka 'long double') type support, but target 'x86_64-unknown-linux-gnu' does not support it}}
+  // expected-error@+2{{'ld' requires  'long_double' (aka 'long double') type support, but target 'x86_64-unknown-linux-gnu' does not support it}}
+#endif
+  st.ld = 0.42;
+}
+
+void assign3() {
+  struct st_long_double2 st;
+#ifndef NOERROR
+  // expected-error@+3{{expression requires  'long_double' (aka 'long double') type support, but target 

[PATCH] D98895: [X86][clang] Disable long double type for -mno-x87 option

2021-11-01 Thread Andrew Savonichev via Phabricator via cfe-commits
asavonic added inline comments.



Comment at: clang/lib/Sema/Sema.cpp:1936
+if (LangOpts.SYCLIsDevice || (LangOpts.OpenMP && LangOpts.OpenMPIsDevice))
+  CheckDeviceType(Ty);
+

erichkeane wrote:
> Should this be a return, or do we still intend the device invocations to go 
> through the below checks too?  
> 
> If so, please write a test for that.
It should be fine either way. New diagnostics are disabled if 
`TI.hasLongDoubleType` and `TI.hasFPReturn` return "true", as expected for SYCL 
and OpenMP device targets.

Added a test for SYCL, OpenMP already has tests with `long double` type.


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D98895

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


[PATCH] D98895: [X86][clang] Disable long double type for -mno-x87 option

2021-10-29 Thread Andrew Savonichev via Phabricator via cfe-commits
asavonic added inline comments.



Comment at: clang/lib/Sema/SemaDecl.cpp:9573
 
-  checkTypeSupport(NewFD->getType(), D.getBeginLoc(), NewFD);
+  if (D.getFunctionDefinitionKind() != FunctionDefinitionKind::Declaration)
+checkTypeSupport(NewFD->getType(), D.getBeginLoc(), NewFD);

erichkeane wrote:
> asavonic wrote:
> > erichkeane wrote:
> > > Why are we not checking declarations here?  This doesn't seem right to 
> > > me.  At least in the offload languages, we still need to check 
> > > declarations.  Also, if something is a problem with a declaration, why is 
> > > it not a problem with defaulted/deleted?
> > > Why are we not checking declarations here?  This doesn't seem right to 
> > > me.  At least in the offload languages, we still need to check 
> > > declarations.
> > 
> > I assume that if if a function is declared and not used, then it is 
> > discarded and no code is generated for it. So it should not really matter 
> > if it uses an "unsupported" type.
> > This is important for `long double`, because there are C standard library 
> > functions that have `long double` arguments. We skip diagnostics for 
> > declarations to avoid errors from standard library headers when the type is 
> > actually not used.
> > 
> > > Also, if something is a problem with a declaration, why is it not a 
> > > problem with defaulted/deleted?
> > 
> > If we can expect that defaulted or deleted functions never result in a code 
> > with unsupported types, then we can exclude them as well. Something like 
> > this perhaps?
> > ```
> > void no_long_double(long double) = delete;
> > ```
> The problem is that these declarations could be called, right?  So are we 
> catching something like:
> 
> ``` void has_long_double(long double d);
> 
> has_long_double(1.0); 
> ```
> 
> The deleted types shouldn't result in code being generated, but default will 
> absolutely result in code being generated. Though I guess I can't think of a 
> situation where we would have a defaulted function that could take a `long 
> double` anyway.
> The problem is that these declarations could be called, right?  So are we 
> catching something like:
> 
> ``` void has_long_double(long double d);
> 
> has_long_double(1.0); 
> ```

Yes, we catch this when the function is called (see below). This is done in 
`Sema::DiagnoseUseOfDecl`.


> The deleted types shouldn't result in code being generated, but default will 
> absolutely result in code being generated. Though I guess I can't think of a 
> situation where we would have a defaulted function that could take a `long 
> double` anyway.

Thank you. I'll update the patch to exclude deleted functions.




Comment at: clang/test/Sema/x86-no-x87.c:35
+#endif
+  return ld_args(x, y);
+}

This is the case where a declaration is called.



Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D98895

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


[PATCH] D98895: [X86][clang] Disable long double type for -mno-x87 option

2021-10-29 Thread Andrew Savonichev via Phabricator via cfe-commits
asavonic added inline comments.



Comment at: clang/lib/Sema/SemaDecl.cpp:9573
 
-  checkTypeSupport(NewFD->getType(), D.getBeginLoc(), NewFD);
+  if (D.getFunctionDefinitionKind() != FunctionDefinitionKind::Declaration)
+checkTypeSupport(NewFD->getType(), D.getBeginLoc(), NewFD);

erichkeane wrote:
> Why are we not checking declarations here?  This doesn't seem right to me.  
> At least in the offload languages, we still need to check declarations.  
> Also, if something is a problem with a declaration, why is it not a problem 
> with defaulted/deleted?
> Why are we not checking declarations here?  This doesn't seem right to me.  
> At least in the offload languages, we still need to check declarations.

I assume that if if a function is declared and not used, then it is discarded 
and no code is generated for it. So it should not really matter if it uses an 
"unsupported" type.
This is important for `long double`, because there are C standard library 
functions that have `long double` arguments. We skip diagnostics for 
declarations to avoid errors from standard library headers when the type is 
actually not used.

> Also, if something is a problem with a declaration, why is it not a problem 
> with defaulted/deleted?

If we can expect that defaulted or deleted functions never result in a code 
with unsupported types, then we can exclude them as well. Something like this 
perhaps?
```
void no_long_double(long double) = delete;
```


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D98895

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


[PATCH] D98895: [X86][clang] Disable long double type for -mno-x87 option

2021-10-28 Thread Andrew Savonichev via Phabricator via cfe-commits
asavonic added a comment.

@pengfei, @erichkeane, please let me know if the patch is OK now, or anything 
else needs to be fixed.


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D98895

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


[PATCH] D98895: [X86][clang] Disable long double type for -mno-x87 option

2021-10-22 Thread Andrew Savonichev via Phabricator via cfe-commits
asavonic updated this revision to Diff 381538.
asavonic retitled this revision from "[X86][Draft] Disable long double type for 
-mno-x87 option" to "[X86][clang] Disable long double type for -mno-x87 option".
asavonic edited the summary of this revision.
asavonic added a comment.
Herald added a reviewer: jdoerfert.
Herald added a subscriber: sstefan1.

Rebased the patch on top of D109315 .

Since the diagnostic is now shared with other targets (SYCL and
OpenMP), I decided to drop all assumptions on optimizations that
we previously discussed. There seems to be no actual use case
where it is important to have them (other than compatibility with
GCC), and they make rules a bit inconsistent.


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D98895

Files:
  clang/include/clang/Basic/DiagnosticSemaKinds.td
  clang/include/clang/Basic/TargetInfo.h
  clang/lib/Basic/TargetInfo.cpp
  clang/lib/Basic/Targets/X86.cpp
  clang/lib/Basic/Targets/X86.h
  clang/lib/Sema/Sema.cpp
  clang/lib/Sema/SemaDecl.cpp
  clang/test/Sema/x86-no-x87.c
  clang/test/Sema/x86_64-no-x87.c

Index: clang/test/Sema/x86_64-no-x87.c
===
--- /dev/null
+++ clang/test/Sema/x86_64-no-x87.c
@@ -0,0 +1,137 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s -triple x86_64-linux-gnu -target-feature -x87
+// RUN: %clang_cc1 -fsyntax-only -verify %s -triple x86_64-linux-gnu -DNOERROR
+
+#ifdef NOERROR
+// expected-no-diagnostics
+#endif
+
+typedef long double long_double;
+
+// Declaration is fine, unless it is called or defined.
+double decl(long_double x, long_double y);
+
+#ifndef NOERROR
+// expected-error@+4{{'def' requires  'long_double' (aka 'long double') type support, but target 'x86_64-unknown-linux-gnu' does not support it}}
+// expected-note@+3{{'def' defined here}}
+// expected-note@+2{{'x' defined here}}
+#endif
+int def(long_double x) {
+#ifndef NOERROR
+// expected-error@+2{{'x' requires  'long_double' (aka 'long double') type support, but target 'x86_64-unknown-linux-gnu' does not support it}}
+#endif
+  return (int)x;
+}
+
+#ifndef NOERROR
+// expected-note@+3{{'ld_args' defined here}}
+// expected-note@+2{{'ld_args' defined here}}
+#endif
+int ld_args(long_double x, long_double y);
+
+int call1(float x, float y) {
+#ifndef NOERROR
+  // expected-error@+2 2{{'ld_args' requires  'long_double' (aka 'long double') type support, but target 'x86_64-unknown-linux-gnu' does not support it}}
+#endif
+  return ld_args(x, y);
+}
+
+#ifndef NOERROR
+// expected-note@+2{{'ld_ret' defined here}}
+#endif
+long_double ld_ret(double x, double y);
+
+int call2(float x, float y) {
+#ifndef NOERROR
+  // expected-error@+2{{'ld_ret' requires  'long_double' (aka 'long double') type support, but target 'x86_64-unknown-linux-gnu' does not support it}}
+#endif
+  return (int)ld_ret(x, y);
+}
+
+int binop(double x, double y) {
+#ifndef NOERROR
+  // expected-error@+2 2{{expression requires  'long_double' (aka 'long double') type support, but target 'x86_64-unknown-linux-gnu' does not support it}}
+#endif
+  double z = (long_double)x * (long_double)y;
+  return (int)z;
+}
+
+void assign1(long_double *ret, double x) {
+#ifndef NOERROR
+  // expected-error@+2{{expression requires  'long_double' (aka 'long double') type support, but target 'x86_64-unknown-linux-gnu' does not support it}}
+#endif
+  *ret = x;
+}
+
+struct st_long_double1 {
+#ifndef NOERROR
+  // expected-note@+2{{'ld' defined here}}
+#endif
+  long_double ld;
+};
+
+struct st_long_double2 {
+#ifndef NOERROR
+  // expected-note@+2{{'ld' defined here}}
+#endif
+  long_double ld;
+};
+
+struct st_long_double3 {
+#ifndef NOERROR
+  // expected-note@+2{{'ld' defined here}}
+#endif
+  long_double ld;
+};
+
+void assign2() {
+  struct st_long_double1 st;
+#ifndef NOERROR
+  // expected-error@+3{{expression requires  'long_double' (aka 'long double') type support, but target 'x86_64-unknown-linux-gnu' does not support it}}
+  // expected-error@+2{{'ld' requires  'long_double' (aka 'long double') type support, but target 'x86_64-unknown-linux-gnu' does not support it}}
+#endif
+  st.ld = 0.42;
+}
+
+void assign3() {
+  struct st_long_double2 st;
+#ifndef NOERROR
+  // expected-error@+3{{expression requires  'long_double' (aka 'long double') type support, but target 'x86_64-unknown-linux-gnu' does not support it}}
+  // expected-error@+2{{'ld' requires  'long_double' (aka 'long double') type support, but target 'x86_64-unknown-linux-gnu' does not support it}}
+#endif
+  st.ld = 42;
+}
+
+void assign4(double d) {
+  struct st_long_double3 st;
+#ifndef NOERROR
+  // expected-error@+3{{expression requires  'long_double' (aka 'long double') type support, but target 'x86_64-unknown-linux-gnu' does not support it}}
+  // expected-error@+2{{'ld' requires  'long_double' (aka 'long double') type support, but target 'x86_64-unknown-linux-gnu' 

[PATCH] D109315: [clang] Check unsupported types in expressions

2021-10-15 Thread Andrew Savonichev via Phabricator via cfe-commits
This revision was landed with ongoing or failed builds.
This revision was automatically updated to reflect the committed changes.
Closed by commit rG3dbcea8b957a: Reland [clang] Check unsupported types in 
expressions (authored by asavonic).

Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D109315

Files:
  clang/include/clang/Basic/DiagnosticSemaKinds.td
  clang/include/clang/Sema/Sema.h
  clang/lib/Sema/Sema.cpp
  clang/lib/Sema/SemaDecl.cpp
  clang/lib/Sema/SemaExpr.cpp
  clang/test/CodeGen/ibm128-unsupported.c
  clang/test/OpenMP/nvptx_unsupported_type_messages.cpp
  clang/test/SemaSYCL/float128.cpp
  clang/test/SemaSYCL/int128.cpp

Index: clang/test/SemaSYCL/int128.cpp
===
--- clang/test/SemaSYCL/int128.cpp
+++ clang/test/SemaSYCL/int128.cpp
@@ -26,19 +26,22 @@
   // expected-note@+1 3{{'A' defined here}}
   __int128 A;
   Z<__int128> C;
-  // expected-error@+2 {{'A' requires 128 bit size '__int128' type support, but device 'spir64' does not support it}}
-  // expected-error@+1 {{'field1' requires 128 bit size '__int128' type support, but device 'spir64' does not support it}}
+  // expected-error@+3 2{{expression requires 128 bit size '__int128' type support, but target 'spir64' does not support it}}
+  // expected-error@+2 {{'A' requires 128 bit size '__int128' type support, but target 'spir64' does not support it}}
+  // expected-error@+1 {{'field1' requires 128 bit size '__int128' type support, but target 'spir64' does not support it}}
   C.field1 = A;
-  // expected-error@+1 {{'bigfield' requires 128 bit size 'Z::BIGTYPE' (aka '__int128') type support, but device 'spir64' does not support it}}
+  // expected-error@+2 {{expression requires 128 bit size 'Z::BIGTYPE' (aka '__int128') type support, but target 'spir64' does not support it}}
+  // expected-error@+1 {{'bigfield' requires 128 bit size 'Z::BIGTYPE' (aka '__int128') type support, but target 'spir64' does not support it}}
   C.bigfield += 1.0;
 
-  // expected-error@+1 {{'A' requires 128 bit size '__int128' type support, but device 'spir64' does not support it}}
+  // expected-error@+1 {{'A' requires 128 bit size '__int128' type support, but target 'spir64' does not support it}}
   auto foo1 = [=]() {
 __int128 AA;
 // expected-note@+2 {{'BB' defined here}}
-// expected-error@+1 {{'A' requires 128 bit size '__int128' type support, but device 'spir64' does not support it}}
+// expected-error@+1 {{'A' requires 128 bit size '__int128' type support, but target 'spir64' does not support it}}
 auto BB = A;
-// expected-error@+1 {{'BB' requires 128 bit size '__int128' type support, but device 'spir64' does not support it}}
+// expected-error@+2 {{expression requires 128 bit size '__int128' type support, but target 'spir64' does not support it}}
+// expected-error@+1 {{'BB' requires 128 bit size '__int128' type support, but target 'spir64' does not support it}}
 BB += 1;
   };
 
@@ -50,7 +53,7 @@
 void foo2(){};
 
 // expected-note@+3 {{'P' defined here}}
-// expected-error@+2 {{'P' requires 128 bit size '__int128' type support, but device 'spir64' does not support it}}
+// expected-error@+2 {{'P' requires 128 bit size '__int128' type support, but target 'spir64' does not support it}}
 // expected-note@+1 2{{'foo' defined here}}
 __int128 foo(__int128 P) { return P; }
 
@@ -58,7 +61,8 @@
   // expected-note@+1 {{'operator __int128' defined here}}
   struct X { operator  __int128() const; } x;
   bool a = false;
-  // expected-error@+1 {{'operator __int128' requires 128 bit size '__int128' type support, but device 'spir64' does not support it}}
+  // expected-error@+2 2{{expression requires 128 bit size '__int128' type support, but target 'spir64' does not support it}}
+  // expected-error@+1 {{'operator __int128' requires 128 bit size '__int128' type support, but target 'spir64' does not support it}}
   a = x == __int128(0);
 }
 
@@ -74,12 +78,14 @@
   host_ok();
   kernel([=]() {
 decltype(CapturedToDevice) D;
-// expected-error@+1 {{'CapturedToDevice' requires 128 bit size '__int128' type support, but device 'spir64' does not support it}}
+// expected-error@+1 {{'CapturedToDevice' requires 128 bit size '__int128' type support, but target 'spir64' does not support it}}
 auto C = CapturedToDevice;
 Z<__int128> S;
-// expected-error@+1 {{'field1' requires 128 bit size '__int128' type support, but device 'spir64' does not support it}}
+// expected-error@+2 {{expression requires 128 bit size '__int128' type support, but target 'spir64' does not support it}}
+// expected-error@+1 {{'field1' requires 128 bit size '__int128' type support, but target 'spir64' does not support it}}
 S.field1 += 1;
-// expected-error@+1 {{'field' requires 128 bit size '__int128' type support, but device 'spir64' does not support it}}
+// 

[PATCH] D109315: [clang] Check unsupported types in expressions

2021-09-20 Thread Andrew Savonichev via Phabricator via cfe-commits
asavonic updated this revision to Diff 373531.

Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D109315

Files:
  clang/include/clang/Basic/DiagnosticSemaKinds.td
  clang/include/clang/Sema/Sema.h
  clang/lib/Sema/Sema.cpp
  clang/lib/Sema/SemaDecl.cpp
  clang/lib/Sema/SemaExpr.cpp
  clang/test/CodeGen/ibm128-unsupported.c
  clang/test/OpenMP/nvptx_unsupported_type_messages.cpp
  clang/test/SemaSYCL/float128.cpp
  clang/test/SemaSYCL/int128.cpp

Index: clang/test/SemaSYCL/int128.cpp
===
--- clang/test/SemaSYCL/int128.cpp
+++ clang/test/SemaSYCL/int128.cpp
@@ -26,19 +26,22 @@
   // expected-note@+1 3{{'A' defined here}}
   __int128 A;
   Z<__int128> C;
-  // expected-error@+2 {{'A' requires 128 bit size '__int128' type support, but device 'spir64' does not support it}}
-  // expected-error@+1 {{'field1' requires 128 bit size '__int128' type support, but device 'spir64' does not support it}}
+  // expected-error@+3 2{{expression requires 128 bit size '__int128' type support, but target 'spir64' does not support it}}
+  // expected-error@+2 {{'A' requires 128 bit size '__int128' type support, but target 'spir64' does not support it}}
+  // expected-error@+1 {{'field1' requires 128 bit size '__int128' type support, but target 'spir64' does not support it}}
   C.field1 = A;
-  // expected-error@+1 {{'bigfield' requires 128 bit size 'Z::BIGTYPE' (aka '__int128') type support, but device 'spir64' does not support it}}
+  // expected-error@+2 {{expression requires 128 bit size 'Z::BIGTYPE' (aka '__int128') type support, but target 'spir64' does not support it}}
+  // expected-error@+1 {{'bigfield' requires 128 bit size 'Z::BIGTYPE' (aka '__int128') type support, but target 'spir64' does not support it}}
   C.bigfield += 1.0;
 
-  // expected-error@+1 {{'A' requires 128 bit size '__int128' type support, but device 'spir64' does not support it}}
+  // expected-error@+1 {{'A' requires 128 bit size '__int128' type support, but target 'spir64' does not support it}}
   auto foo1 = [=]() {
 __int128 AA;
 // expected-note@+2 {{'BB' defined here}}
-// expected-error@+1 {{'A' requires 128 bit size '__int128' type support, but device 'spir64' does not support it}}
+// expected-error@+1 {{'A' requires 128 bit size '__int128' type support, but target 'spir64' does not support it}}
 auto BB = A;
-// expected-error@+1 {{'BB' requires 128 bit size '__int128' type support, but device 'spir64' does not support it}}
+// expected-error@+2 {{expression requires 128 bit size '__int128' type support, but target 'spir64' does not support it}}
+// expected-error@+1 {{'BB' requires 128 bit size '__int128' type support, but target 'spir64' does not support it}}
 BB += 1;
   };
 
@@ -50,7 +53,7 @@
 void foo2(){};
 
 // expected-note@+3 {{'P' defined here}}
-// expected-error@+2 {{'P' requires 128 bit size '__int128' type support, but device 'spir64' does not support it}}
+// expected-error@+2 {{'P' requires 128 bit size '__int128' type support, but target 'spir64' does not support it}}
 // expected-note@+1 2{{'foo' defined here}}
 __int128 foo(__int128 P) { return P; }
 
@@ -58,7 +61,8 @@
   // expected-note@+1 {{'operator __int128' defined here}}
   struct X { operator  __int128() const; } x;
   bool a = false;
-  // expected-error@+1 {{'operator __int128' requires 128 bit size '__int128' type support, but device 'spir64' does not support it}}
+  // expected-error@+2 2{{expression requires 128 bit size '__int128' type support, but target 'spir64' does not support it}}
+  // expected-error@+1 {{'operator __int128' requires 128 bit size '__int128' type support, but target 'spir64' does not support it}}
   a = x == __int128(0);
 }
 
@@ -74,12 +78,14 @@
   host_ok();
   kernel([=]() {
 decltype(CapturedToDevice) D;
-// expected-error@+1 {{'CapturedToDevice' requires 128 bit size '__int128' type support, but device 'spir64' does not support it}}
+// expected-error@+1 {{'CapturedToDevice' requires 128 bit size '__int128' type support, but target 'spir64' does not support it}}
 auto C = CapturedToDevice;
 Z<__int128> S;
-// expected-error@+1 {{'field1' requires 128 bit size '__int128' type support, but device 'spir64' does not support it}}
+// expected-error@+2 {{expression requires 128 bit size '__int128' type support, but target 'spir64' does not support it}}
+// expected-error@+1 {{'field1' requires 128 bit size '__int128' type support, but target 'spir64' does not support it}}
 S.field1 += 1;
-// expected-error@+1 {{'field' requires 128 bit size '__int128' type support, but device 'spir64' does not support it}}
+// expected-error@+2 {{expression requires 128 bit size '__int128' type support, but target 'spir64' does not support it}}
+// expected-error@+1 {{'field' requires 128 bit size '__int128' type support, but 

[PATCH] D109315: [clang] Check unsupported types in expressions

2021-09-20 Thread Andrew Savonichev via Phabricator via cfe-commits
asavonic reopened this revision.
asavonic added a comment.
This revision is now accepted and ready to land.

This is weird... Buildbot reported that `lock/omp_init_lock.c` test
crashed with SIGSEGV, but I cannot reproduce this on my machine.

I added a check for a null QualType; not sure if it fixes the issue
with the test.


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D109315

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


[PATCH] D109315: [clang] Check unsupported types in expressions

2021-09-13 Thread Andrew Savonichev via Phabricator via cfe-commits
This revision was automatically updated to reflect the committed changes.
Closed by commit rGec6c847179fd: [clang] Check unsupported types in expressions 
(authored by asavonic).

Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D109315

Files:
  clang/include/clang/Basic/DiagnosticSemaKinds.td
  clang/include/clang/Sema/Sema.h
  clang/lib/Sema/Sema.cpp
  clang/lib/Sema/SemaDecl.cpp
  clang/lib/Sema/SemaExpr.cpp
  clang/test/CodeGen/ibm128-unsupported.c
  clang/test/OpenMP/nvptx_unsupported_type_messages.cpp
  clang/test/SemaSYCL/float128.cpp
  clang/test/SemaSYCL/int128.cpp

Index: clang/test/SemaSYCL/int128.cpp
===
--- clang/test/SemaSYCL/int128.cpp
+++ clang/test/SemaSYCL/int128.cpp
@@ -26,19 +26,22 @@
   // expected-note@+1 3{{'A' defined here}}
   __int128 A;
   Z<__int128> C;
-  // expected-error@+2 {{'A' requires 128 bit size '__int128' type support, but device 'spir64' does not support it}}
-  // expected-error@+1 {{'field1' requires 128 bit size '__int128' type support, but device 'spir64' does not support it}}
+  // expected-error@+3 2{{expression requires 128 bit size '__int128' type support, but target 'spir64' does not support it}}
+  // expected-error@+2 {{'A' requires 128 bit size '__int128' type support, but target 'spir64' does not support it}}
+  // expected-error@+1 {{'field1' requires 128 bit size '__int128' type support, but target 'spir64' does not support it}}
   C.field1 = A;
-  // expected-error@+1 {{'bigfield' requires 128 bit size 'Z::BIGTYPE' (aka '__int128') type support, but device 'spir64' does not support it}}
+  // expected-error@+2 {{expression requires 128 bit size 'Z::BIGTYPE' (aka '__int128') type support, but target 'spir64' does not support it}}
+  // expected-error@+1 {{'bigfield' requires 128 bit size 'Z::BIGTYPE' (aka '__int128') type support, but target 'spir64' does not support it}}
   C.bigfield += 1.0;
 
-  // expected-error@+1 {{'A' requires 128 bit size '__int128' type support, but device 'spir64' does not support it}}
+  // expected-error@+1 {{'A' requires 128 bit size '__int128' type support, but target 'spir64' does not support it}}
   auto foo1 = [=]() {
 __int128 AA;
 // expected-note@+2 {{'BB' defined here}}
-// expected-error@+1 {{'A' requires 128 bit size '__int128' type support, but device 'spir64' does not support it}}
+// expected-error@+1 {{'A' requires 128 bit size '__int128' type support, but target 'spir64' does not support it}}
 auto BB = A;
-// expected-error@+1 {{'BB' requires 128 bit size '__int128' type support, but device 'spir64' does not support it}}
+// expected-error@+2 {{expression requires 128 bit size '__int128' type support, but target 'spir64' does not support it}}
+// expected-error@+1 {{'BB' requires 128 bit size '__int128' type support, but target 'spir64' does not support it}}
 BB += 1;
   };
 
@@ -50,7 +53,7 @@
 void foo2(){};
 
 // expected-note@+3 {{'P' defined here}}
-// expected-error@+2 {{'P' requires 128 bit size '__int128' type support, but device 'spir64' does not support it}}
+// expected-error@+2 {{'P' requires 128 bit size '__int128' type support, but target 'spir64' does not support it}}
 // expected-note@+1 2{{'foo' defined here}}
 __int128 foo(__int128 P) { return P; }
 
@@ -58,7 +61,8 @@
   // expected-note@+1 {{'operator __int128' defined here}}
   struct X { operator  __int128() const; } x;
   bool a = false;
-  // expected-error@+1 {{'operator __int128' requires 128 bit size '__int128' type support, but device 'spir64' does not support it}}
+  // expected-error@+2 2{{expression requires 128 bit size '__int128' type support, but target 'spir64' does not support it}}
+  // expected-error@+1 {{'operator __int128' requires 128 bit size '__int128' type support, but target 'spir64' does not support it}}
   a = x == __int128(0);
 }
 
@@ -74,12 +78,14 @@
   host_ok();
   kernel([=]() {
 decltype(CapturedToDevice) D;
-// expected-error@+1 {{'CapturedToDevice' requires 128 bit size '__int128' type support, but device 'spir64' does not support it}}
+// expected-error@+1 {{'CapturedToDevice' requires 128 bit size '__int128' type support, but target 'spir64' does not support it}}
 auto C = CapturedToDevice;
 Z<__int128> S;
-// expected-error@+1 {{'field1' requires 128 bit size '__int128' type support, but device 'spir64' does not support it}}
+// expected-error@+2 {{expression requires 128 bit size '__int128' type support, but target 'spir64' does not support it}}
+// expected-error@+1 {{'field1' requires 128 bit size '__int128' type support, but target 'spir64' does not support it}}
 S.field1 += 1;
-// expected-error@+1 {{'field' requires 128 bit size '__int128' type support, but device 'spir64' does not support it}}
+// expected-error@+2 {{expression requires 128 bit size '__int128' type 

[PATCH] D109315: [clang] Check unsupported types in expressions

2021-09-10 Thread Andrew Savonichev via Phabricator via cfe-commits
asavonic updated this revision to Diff 371912.
asavonic added a comment.

Rebased


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D109315

Files:
  clang/include/clang/Basic/DiagnosticSemaKinds.td
  clang/include/clang/Sema/Sema.h
  clang/lib/Sema/Sema.cpp
  clang/lib/Sema/SemaDecl.cpp
  clang/lib/Sema/SemaExpr.cpp
  clang/test/CodeGen/ibm128-unsupported.c
  clang/test/OpenMP/nvptx_unsupported_type_messages.cpp
  clang/test/SemaSYCL/float128.cpp
  clang/test/SemaSYCL/int128.cpp

Index: clang/test/SemaSYCL/int128.cpp
===
--- clang/test/SemaSYCL/int128.cpp
+++ clang/test/SemaSYCL/int128.cpp
@@ -26,19 +26,22 @@
   // expected-note@+1 3{{'A' defined here}}
   __int128 A;
   Z<__int128> C;
-  // expected-error@+2 {{'A' requires 128 bit size '__int128' type support, but device 'spir64' does not support it}}
-  // expected-error@+1 {{'field1' requires 128 bit size '__int128' type support, but device 'spir64' does not support it}}
+  // expected-error@+3 2{{expression requires 128 bit size '__int128' type support, but target 'spir64' does not support it}}
+  // expected-error@+2 {{'A' requires 128 bit size '__int128' type support, but target 'spir64' does not support it}}
+  // expected-error@+1 {{'field1' requires 128 bit size '__int128' type support, but target 'spir64' does not support it}}
   C.field1 = A;
-  // expected-error@+1 {{'bigfield' requires 128 bit size 'Z::BIGTYPE' (aka '__int128') type support, but device 'spir64' does not support it}}
+  // expected-error@+2 {{expression requires 128 bit size 'Z::BIGTYPE' (aka '__int128') type support, but target 'spir64' does not support it}}
+  // expected-error@+1 {{'bigfield' requires 128 bit size 'Z::BIGTYPE' (aka '__int128') type support, but target 'spir64' does not support it}}
   C.bigfield += 1.0;
 
-  // expected-error@+1 {{'A' requires 128 bit size '__int128' type support, but device 'spir64' does not support it}}
+  // expected-error@+1 {{'A' requires 128 bit size '__int128' type support, but target 'spir64' does not support it}}
   auto foo1 = [=]() {
 __int128 AA;
 // expected-note@+2 {{'BB' defined here}}
-// expected-error@+1 {{'A' requires 128 bit size '__int128' type support, but device 'spir64' does not support it}}
+// expected-error@+1 {{'A' requires 128 bit size '__int128' type support, but target 'spir64' does not support it}}
 auto BB = A;
-// expected-error@+1 {{'BB' requires 128 bit size '__int128' type support, but device 'spir64' does not support it}}
+// expected-error@+2 {{expression requires 128 bit size '__int128' type support, but target 'spir64' does not support it}}
+// expected-error@+1 {{'BB' requires 128 bit size '__int128' type support, but target 'spir64' does not support it}}
 BB += 1;
   };
 
@@ -50,7 +53,7 @@
 void foo2(){};
 
 // expected-note@+3 {{'P' defined here}}
-// expected-error@+2 {{'P' requires 128 bit size '__int128' type support, but device 'spir64' does not support it}}
+// expected-error@+2 {{'P' requires 128 bit size '__int128' type support, but target 'spir64' does not support it}}
 // expected-note@+1 2{{'foo' defined here}}
 __int128 foo(__int128 P) { return P; }
 
@@ -58,7 +61,8 @@
   // expected-note@+1 {{'operator __int128' defined here}}
   struct X { operator  __int128() const; } x;
   bool a = false;
-  // expected-error@+1 {{'operator __int128' requires 128 bit size '__int128' type support, but device 'spir64' does not support it}}
+  // expected-error@+2 2{{expression requires 128 bit size '__int128' type support, but target 'spir64' does not support it}}
+  // expected-error@+1 {{'operator __int128' requires 128 bit size '__int128' type support, but target 'spir64' does not support it}}
   a = x == __int128(0);
 }
 
@@ -74,12 +78,14 @@
   host_ok();
   kernel([=]() {
 decltype(CapturedToDevice) D;
-// expected-error@+1 {{'CapturedToDevice' requires 128 bit size '__int128' type support, but device 'spir64' does not support it}}
+// expected-error@+1 {{'CapturedToDevice' requires 128 bit size '__int128' type support, but target 'spir64' does not support it}}
 auto C = CapturedToDevice;
 Z<__int128> S;
-// expected-error@+1 {{'field1' requires 128 bit size '__int128' type support, but device 'spir64' does not support it}}
+// expected-error@+2 {{expression requires 128 bit size '__int128' type support, but target 'spir64' does not support it}}
+// expected-error@+1 {{'field1' requires 128 bit size '__int128' type support, but target 'spir64' does not support it}}
 S.field1 += 1;
-// expected-error@+1 {{'field' requires 128 bit size '__int128' type support, but device 'spir64' does not support it}}
+// expected-error@+2 {{expression requires 128 bit size '__int128' type support, but target 'spir64' does not support it}}
+// expected-error@+1 {{'field' requires 128 bit 

[PATCH] D109315: [clang] Check unsupported types in expressions

2021-09-09 Thread Andrew Savonichev via Phabricator via cfe-commits
asavonic updated this revision to Diff 371693.
asavonic added a comment.

- Reworded the diagnostic.


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D109315

Files:
  clang/include/clang/Basic/DiagnosticSemaKinds.td
  clang/include/clang/Sema/Sema.h
  clang/lib/Sema/Sema.cpp
  clang/lib/Sema/SemaDecl.cpp
  clang/lib/Sema/SemaExpr.cpp
  clang/test/OpenMP/nvptx_unsupported_type_messages.cpp
  clang/test/SemaSYCL/float128.cpp
  clang/test/SemaSYCL/int128.cpp

Index: clang/test/SemaSYCL/int128.cpp
===
--- clang/test/SemaSYCL/int128.cpp
+++ clang/test/SemaSYCL/int128.cpp
@@ -26,19 +26,22 @@
   // expected-note@+1 3{{'A' defined here}}
   __int128 A;
   Z<__int128> C;
-  // expected-error@+2 {{'A' requires 128 bit size '__int128' type support, but device 'spir64' does not support it}}
-  // expected-error@+1 {{'field1' requires 128 bit size '__int128' type support, but device 'spir64' does not support it}}
+  // expected-error@+3 2{{expression requires 128 bit size '__int128' type support, but target 'spir64' does not support it}}
+  // expected-error@+2 {{'A' requires 128 bit size '__int128' type support, but target 'spir64' does not support it}}
+  // expected-error@+1 {{'field1' requires 128 bit size '__int128' type support, but target 'spir64' does not support it}}
   C.field1 = A;
-  // expected-error@+1 {{'bigfield' requires 128 bit size 'Z::BIGTYPE' (aka '__int128') type support, but device 'spir64' does not support it}}
+  // expected-error@+2 {{expression requires 128 bit size 'Z::BIGTYPE' (aka '__int128') type support, but target 'spir64' does not support it}}
+  // expected-error@+1 {{'bigfield' requires 128 bit size 'Z::BIGTYPE' (aka '__int128') type support, but target 'spir64' does not support it}}
   C.bigfield += 1.0;
 
-  // expected-error@+1 {{'A' requires 128 bit size '__int128' type support, but device 'spir64' does not support it}}
+  // expected-error@+1 {{'A' requires 128 bit size '__int128' type support, but target 'spir64' does not support it}}
   auto foo1 = [=]() {
 __int128 AA;
 // expected-note@+2 {{'BB' defined here}}
-// expected-error@+1 {{'A' requires 128 bit size '__int128' type support, but device 'spir64' does not support it}}
+// expected-error@+1 {{'A' requires 128 bit size '__int128' type support, but target 'spir64' does not support it}}
 auto BB = A;
-// expected-error@+1 {{'BB' requires 128 bit size '__int128' type support, but device 'spir64' does not support it}}
+// expected-error@+2 {{expression requires 128 bit size '__int128' type support, but target 'spir64' does not support it}}
+// expected-error@+1 {{'BB' requires 128 bit size '__int128' type support, but target 'spir64' does not support it}}
 BB += 1;
   };
 
@@ -50,7 +53,7 @@
 void foo2(){};
 
 // expected-note@+3 {{'P' defined here}}
-// expected-error@+2 {{'P' requires 128 bit size '__int128' type support, but device 'spir64' does not support it}}
+// expected-error@+2 {{'P' requires 128 bit size '__int128' type support, but target 'spir64' does not support it}}
 // expected-note@+1 2{{'foo' defined here}}
 __int128 foo(__int128 P) { return P; }
 
@@ -58,7 +61,8 @@
   // expected-note@+1 {{'operator __int128' defined here}}
   struct X { operator  __int128() const; } x;
   bool a = false;
-  // expected-error@+1 {{'operator __int128' requires 128 bit size '__int128' type support, but device 'spir64' does not support it}}
+  // expected-error@+2 2{{expression requires 128 bit size '__int128' type support, but target 'spir64' does not support it}}
+  // expected-error@+1 {{'operator __int128' requires 128 bit size '__int128' type support, but target 'spir64' does not support it}}
   a = x == __int128(0);
 }
 
@@ -74,12 +78,14 @@
   host_ok();
   kernel([=]() {
 decltype(CapturedToDevice) D;
-// expected-error@+1 {{'CapturedToDevice' requires 128 bit size '__int128' type support, but device 'spir64' does not support it}}
+// expected-error@+1 {{'CapturedToDevice' requires 128 bit size '__int128' type support, but target 'spir64' does not support it}}
 auto C = CapturedToDevice;
 Z<__int128> S;
-// expected-error@+1 {{'field1' requires 128 bit size '__int128' type support, but device 'spir64' does not support it}}
+// expected-error@+2 {{expression requires 128 bit size '__int128' type support, but target 'spir64' does not support it}}
+// expected-error@+1 {{'field1' requires 128 bit size '__int128' type support, but target 'spir64' does not support it}}
 S.field1 += 1;
-// expected-error@+1 {{'field' requires 128 bit size '__int128' type support, but device 'spir64' does not support it}}
+// expected-error@+2 {{expression requires 128 bit size '__int128' type support, but target 'spir64' does not support it}}
+// expected-error@+1 {{'field' requires 128 bit size '__int128' type 

[PATCH] D109315: [clang] Check unsupported types in expressions

2021-09-06 Thread Andrew Savonichev via Phabricator via cfe-commits
asavonic added inline comments.



Comment at: clang/include/clang/Basic/DiagnosticSemaKinds.td:10687
 def err_device_unsupported_type
-: Error<"%0 requires %select{|%2 bit size}1 %3 type support, but device "
-"'%4' does not support it">;
+: Error<"%select{|%1 bit size}0 %2 type is not supported for target '%3'">;
 def err_omp_lambda_capture_in_declare_target_not_to : Error<

Fznamznon wrote:
> Maybe it is just me, but the old version was a bit more clear since it 
> pointed to the wrong declaration. Now looking at the tests I see that clang 
> ends up emitting several identical diagnostics at the same line, but they 
> point to the different declarations/expressions used on this line. Should we 
> still mention which concrete declaration/expression the diagnostic is about?
Agree, but I couldn't figure out good wording for the diagnostic that works 
well for both decl and expr cases.


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D109315

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


[PATCH] D98895: [X86][Draft] Disable long double type for -mno-x87 option

2021-09-06 Thread Andrew Savonichev via Phabricator via cfe-commits
asavonic added a comment.

Thanks @erichkeane. SPIR-V diagnostics seem to work fine. There are a few cases 
that are not handled, so I submitted D109315  
to review them separately.


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D98895

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


[PATCH] D109315: [clang] Check unsupported types in expressions

2021-09-06 Thread Andrew Savonichev via Phabricator via cfe-commits
asavonic created this revision.
asavonic added reviewers: erichkeane, Fznamznon.
asavonic requested review of this revision.
Herald added a reviewer: jdoerfert.
Herald added subscribers: cfe-commits, sstefan1.
Herald added a project: clang.

The patch adds diagnostics for cases like:

  float F3 = ((__float128)F1 * (__float128)F2) / 2.0f;

Sema::checkDeviceDecl (renamed to checkTypeSupport) is changed to work
with a type without the corresponding ValueDecl. It is also refactored
so that host diagnostics for unsupported types can be added here as
well.


Repository:
  rG LLVM Github Monorepo

https://reviews.llvm.org/D109315

Files:
  clang/include/clang/Basic/DiagnosticSemaKinds.td
  clang/include/clang/Sema/Sema.h
  clang/lib/Sema/Sema.cpp
  clang/lib/Sema/SemaDecl.cpp
  clang/lib/Sema/SemaExpr.cpp
  clang/test/OpenMP/nvptx_unsupported_type_messages.cpp
  clang/test/SemaSYCL/float128.cpp
  clang/test/SemaSYCL/int128.cpp

Index: clang/test/SemaSYCL/int128.cpp
===
--- clang/test/SemaSYCL/int128.cpp
+++ clang/test/SemaSYCL/int128.cpp
@@ -26,19 +26,18 @@
   // expected-note@+1 3{{'A' defined here}}
   __int128 A;
   Z<__int128> C;
-  // expected-error@+2 {{'A' requires 128 bit size '__int128' type support, but device 'spir64' does not support it}}
-  // expected-error@+1 {{'field1' requires 128 bit size '__int128' type support, but device 'spir64' does not support it}}
+  // expected-error@+1 4{{128 bit size '__int128' type is not supported for target 'spir64'}}
   C.field1 = A;
-  // expected-error@+1 {{'bigfield' requires 128 bit size 'Z::BIGTYPE' (aka '__int128') type support, but device 'spir64' does not support it}}
+  // expected-error@+1 2{{128 bit size 'Z::BIGTYPE' (aka '__int128') type is not supported for target 'spir64'}}
   C.bigfield += 1.0;
 
-  // expected-error@+1 {{'A' requires 128 bit size '__int128' type support, but device 'spir64' does not support it}}
+  // expected-error@+1 {{128 bit size '__int128' type is not supported for target 'spir64'}}
   auto foo1 = [=]() {
 __int128 AA;
 // expected-note@+2 {{'BB' defined here}}
-// expected-error@+1 {{'A' requires 128 bit size '__int128' type support, but device 'spir64' does not support it}}
+// expected-error@+1 {{128 bit size '__int128' type is not supported for target 'spir64'}}
 auto BB = A;
-// expected-error@+1 {{'BB' requires 128 bit size '__int128' type support, but device 'spir64' does not support it}}
+// expected-error@+1 2{{128 bit size '__int128' type is not supported for target 'spir64'}}
 BB += 1;
   };
 
@@ -50,7 +49,7 @@
 void foo2(){};
 
 // expected-note@+3 {{'P' defined here}}
-// expected-error@+2 {{'P' requires 128 bit size '__int128' type support, but device 'spir64' does not support it}}
+// expected-error@+2 {{128 bit size '__int128' type is not supported for target 'spir64'}}
 // expected-note@+1 2{{'foo' defined here}}
 __int128 foo(__int128 P) { return P; }
 
@@ -58,7 +57,7 @@
   // expected-note@+1 {{'operator __int128' defined here}}
   struct X { operator  __int128() const; } x;
   bool a = false;
-  // expected-error@+1 {{'operator __int128' requires 128 bit size '__int128' type support, but device 'spir64' does not support it}}
+  // expected-error@+1 3{{128 bit size '__int128' type is not supported for target 'spir64'}}
   a = x == __int128(0);
 }
 
@@ -74,12 +73,12 @@
   host_ok();
   kernel([=]() {
 decltype(CapturedToDevice) D;
-// expected-error@+1 {{'CapturedToDevice' requires 128 bit size '__int128' type support, but device 'spir64' does not support it}}
+// expected-error@+1 {{128 bit size '__int128' type is not supported for target 'spir64'}}
 auto C = CapturedToDevice;
 Z<__int128> S;
-// expected-error@+1 {{'field1' requires 128 bit size '__int128' type support, but device 'spir64' does not support it}}
+// expected-error@+1 2{{128 bit size '__int128' type is not supported for target 'spir64'}}
 S.field1 += 1;
-// expected-error@+1 {{'field' requires 128 bit size '__int128' type support, but device 'spir64' does not support it}}
+// expected-error@+1 2{{128 bit size '__int128' type is not supported for target 'spir64'}}
 S.field = 1;
   });
 
@@ -88,8 +87,8 @@
 usage();
 // expected-note@+1 {{'' defined here}}
 BIGTY ;
-// expected-error@+3 {{'' requires 128 bit size 'BIGTY' (aka 'unsigned __int128') type support, but device 'spir64' does not support it}}
-// expected-error@+2 2{{'foo' requires 128 bit size '__int128' type support, but device 'spir64' does not support it}}
+// expected-error@+3 2{{128 bit size '__int128' type is not supported for target 'spir64'}}
+// expected-error@+2 1{{128 bit size 'BIGTY' (aka 'unsigned __int128') type is not supported for target 'spir64'}}
 // expected-note@+1 1{{called by 'operator()'}}
 auto A = foo();
 // expected-note@+1 {{called by 'operator()'}}
Index: 

[PATCH] D98895: [X86][Draft] Disable long double type for -mno-x87 option

2021-06-16 Thread Andrew Savonichev via Phabricator via cfe-commits
asavonic added a comment.

@erichkeane, can you please check if this patch is OK for Clang?


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D98895

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


[PATCH] D101156: [Clang] Support a user-defined __dso_handle

2021-06-07 Thread Andrew Savonichev via Phabricator via cfe-commits
This revision was automatically updated to reflect the committed changes.
Closed by commit rGb31f41e78b27: [Clang] Support a user-defined __dso_handle 
(authored by asavonic).

Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D101156

Files:
  clang/lib/CodeGen/CodeGenModule.cpp
  clang/test/CodeGenCXX/dso-handle-custom.cpp


Index: clang/test/CodeGenCXX/dso-handle-custom.cpp
===
--- /dev/null
+++ clang/test/CodeGenCXX/dso-handle-custom.cpp
@@ -0,0 +1,23 @@
+// RUN: %clang_cc1 -triple x86_64-unknown-linux-gnu -emit-llvm -fexceptions %s 
-o - | FileCheck %s --check-prefixes CHECK,CHECK-DEFAULT
+// RUN: %clang_cc1 -triple x86_64-unknown-linux-gnu -emit-llvm -fexceptions %s 
-o - -DHIDDEN | FileCheck %s --check-prefixes CHECK,CHECK-HIDDEN
+
+class A {
+public:
+  ~A();
+} a;
+
+// CHECK-DEFAULT: @__dso_handle = global i8* bitcast (i8** @__dso_handle to 
i8*), align 8
+// CHECK-HIDDEN: @__dso_handle = hidden global i8* bitcast (i8** @__dso_handle 
to i8*), align 8
+// CHECK: define internal void @__cxx_global_var_init()
+// CHECK:   call i32 @__cxa_atexit({{.*}}, {{.*}}, i8* bitcast (i8** 
@__dso_handle to i8*))
+
+#ifdef HIDDEN
+void *__dso_handle __attribute__((__visibility__("hidden"))) = &__dso_handle;
+#else
+void *__dso_handle = &__dso_handle;
+#endif
+
+void use(void *);
+void use_dso_handle() {
+  use(__dso_handle);
+}
Index: clang/lib/CodeGen/CodeGenModule.cpp
===
--- clang/lib/CodeGen/CodeGenModule.cpp
+++ clang/lib/CodeGen/CodeGenModule.cpp
@@ -4284,7 +4284,7 @@
   OpenMPRuntime->emitTargetGlobalVariable(D))
 return;
 
-  llvm::Constant *Init = nullptr;
+  llvm::TrackingVH Init;
   bool NeedsGlobalCtor = false;
   bool NeedsGlobalDtor =
   D->needsDestruction(getContext()) == QualType::DK_cxx_destructor;
@@ -4330,9 +4330,8 @@
   } else {
 initializedGlobalDecl = GlobalDecl(D);
 emitter.emplace(*this);
-Init = emitter->tryEmitForInitializer(*InitDecl);
-
-if (!Init) {
+llvm::Constant *Initializer = emitter->tryEmitForInitializer(*InitDecl);
+if (!Initializer) {
   QualType T = InitExpr->getType();
   if (D->getType()->isReferenceType())
 T = D->getType();
@@ -4345,6 +4344,7 @@
 Init = llvm::UndefValue::get(getTypes().ConvertType(T));
   }
 } else {
+  Init = Initializer;
   // We don't need an initializer, so remove the entry for the delayed
   // initializer position (just in case this entry was delayed) if we
   // also don't need to register a destructor.


Index: clang/test/CodeGenCXX/dso-handle-custom.cpp
===
--- /dev/null
+++ clang/test/CodeGenCXX/dso-handle-custom.cpp
@@ -0,0 +1,23 @@
+// RUN: %clang_cc1 -triple x86_64-unknown-linux-gnu -emit-llvm -fexceptions %s -o - | FileCheck %s --check-prefixes CHECK,CHECK-DEFAULT
+// RUN: %clang_cc1 -triple x86_64-unknown-linux-gnu -emit-llvm -fexceptions %s -o - -DHIDDEN | FileCheck %s --check-prefixes CHECK,CHECK-HIDDEN
+
+class A {
+public:
+  ~A();
+} a;
+
+// CHECK-DEFAULT: @__dso_handle = global i8* bitcast (i8** @__dso_handle to i8*), align 8
+// CHECK-HIDDEN: @__dso_handle = hidden global i8* bitcast (i8** @__dso_handle to i8*), align 8
+// CHECK: define internal void @__cxx_global_var_init()
+// CHECK:   call i32 @__cxa_atexit({{.*}}, {{.*}}, i8* bitcast (i8** @__dso_handle to i8*))
+
+#ifdef HIDDEN
+void *__dso_handle __attribute__((__visibility__("hidden"))) = &__dso_handle;
+#else
+void *__dso_handle = &__dso_handle;
+#endif
+
+void use(void *);
+void use_dso_handle() {
+  use(__dso_handle);
+}
Index: clang/lib/CodeGen/CodeGenModule.cpp
===
--- clang/lib/CodeGen/CodeGenModule.cpp
+++ clang/lib/CodeGen/CodeGenModule.cpp
@@ -4284,7 +4284,7 @@
   OpenMPRuntime->emitTargetGlobalVariable(D))
 return;
 
-  llvm::Constant *Init = nullptr;
+  llvm::TrackingVH Init;
   bool NeedsGlobalCtor = false;
   bool NeedsGlobalDtor =
   D->needsDestruction(getContext()) == QualType::DK_cxx_destructor;
@@ -4330,9 +4330,8 @@
   } else {
 initializedGlobalDecl = GlobalDecl(D);
 emitter.emplace(*this);
-Init = emitter->tryEmitForInitializer(*InitDecl);
-
-if (!Init) {
+llvm::Constant *Initializer = emitter->tryEmitForInitializer(*InitDecl);
+if (!Initializer) {
   QualType T = InitExpr->getType();
   if (D->getType()->isReferenceType())
 T = D->getType();
@@ -4345,6 +4344,7 @@
 Init = llvm::UndefValue::get(getTypes().ConvertType(T));
   }
 } else {
+  Init = Initializer;
   // We don't need an initializer, so remove the entry for the delayed
   // initializer position (just in case this entry was delayed) if we
   // also don't need to register a destructor.

[PATCH] D101156: [Clang] Support a user-defined __dso_handle

2021-06-06 Thread Andrew Savonichev via Phabricator via cfe-commits
asavonic added inline comments.



Comment at: clang/lib/CodeGen/CodeGenModule.cpp:4425
+  if (ReplaceInitWithGV)
+Init = llvm::ConstantExpr::getBitCast(GV, GV->getValueType());
+

rjmccall wrote:
> Can we actually do this bitcast for arbitrary initializers?  This seems 
> problematic.
> 
> I think we just need to hold `Init` in an `llvm::TrackingVH` across the call 
> to `GetAddrOfGlobalVar`.
Thanks a lot! `TrackingVH` works great, with a few adjustments because it 
cannot be checked for nullptr.


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

https://reviews.llvm.org/D101156

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


[PATCH] D101156: [Clang] Support a user-defined __dso_handle

2021-06-06 Thread Andrew Savonichev via Phabricator via cfe-commits
asavonic updated this revision to Diff 350134.
asavonic edited the summary of this revision.
asavonic added a comment.

- Used `llvm::TrackingVH` to track Init changes.


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

https://reviews.llvm.org/D101156

Files:
  clang/lib/CodeGen/CodeGenModule.cpp
  clang/test/CodeGenCXX/dso-handle-custom.cpp


Index: clang/test/CodeGenCXX/dso-handle-custom.cpp
===
--- /dev/null
+++ clang/test/CodeGenCXX/dso-handle-custom.cpp
@@ -0,0 +1,23 @@
+// RUN: %clang_cc1 -triple x86_64-unknown-linux-gnu -emit-llvm -fexceptions %s 
-o - | FileCheck %s --check-prefixes CHECK,CHECK-DEFAULT
+// RUN: %clang_cc1 -triple x86_64-unknown-linux-gnu -emit-llvm -fexceptions %s 
-o - -DHIDDEN | FileCheck %s --check-prefixes CHECK,CHECK-HIDDEN
+
+class A {
+public:
+  ~A();
+} a;
+
+// CHECK-DEFAULT: @__dso_handle = global i8* bitcast (i8** @__dso_handle to 
i8*), align 8
+// CHECK-HIDDEN: @__dso_handle = hidden global i8* bitcast (i8** @__dso_handle 
to i8*), align 8
+// CHECK: define internal void @__cxx_global_var_init()
+// CHECK:   call i32 @__cxa_atexit({{.*}}, {{.*}}, i8* bitcast (i8** 
@__dso_handle to i8*))
+
+#ifdef HIDDEN
+void *__dso_handle __attribute__((__visibility__("hidden"))) = &__dso_handle;
+#else
+void *__dso_handle = &__dso_handle;
+#endif
+
+void use(void *);
+void use_dso_handle() {
+  use(__dso_handle);
+}
Index: clang/lib/CodeGen/CodeGenModule.cpp
===
--- clang/lib/CodeGen/CodeGenModule.cpp
+++ clang/lib/CodeGen/CodeGenModule.cpp
@@ -4284,7 +4284,7 @@
   OpenMPRuntime->emitTargetGlobalVariable(D))
 return;
 
-  llvm::Constant *Init = nullptr;
+  llvm::TrackingVH Init;
   bool NeedsGlobalCtor = false;
   bool NeedsGlobalDtor =
   D->needsDestruction(getContext()) == QualType::DK_cxx_destructor;
@@ -4330,9 +4330,8 @@
   } else {
 initializedGlobalDecl = GlobalDecl(D);
 emitter.emplace(*this);
-Init = emitter->tryEmitForInitializer(*InitDecl);
-
-if (!Init) {
+llvm::Constant *Initializer = emitter->tryEmitForInitializer(*InitDecl);
+if (!Initializer) {
   QualType T = InitExpr->getType();
   if (D->getType()->isReferenceType())
 T = D->getType();
@@ -4345,6 +4344,7 @@
 Init = llvm::UndefValue::get(getTypes().ConvertType(T));
   }
 } else {
+  Init = Initializer;
   // We don't need an initializer, so remove the entry for the delayed
   // initializer position (just in case this entry was delayed) if we
   // also don't need to register a destructor.


Index: clang/test/CodeGenCXX/dso-handle-custom.cpp
===
--- /dev/null
+++ clang/test/CodeGenCXX/dso-handle-custom.cpp
@@ -0,0 +1,23 @@
+// RUN: %clang_cc1 -triple x86_64-unknown-linux-gnu -emit-llvm -fexceptions %s -o - | FileCheck %s --check-prefixes CHECK,CHECK-DEFAULT
+// RUN: %clang_cc1 -triple x86_64-unknown-linux-gnu -emit-llvm -fexceptions %s -o - -DHIDDEN | FileCheck %s --check-prefixes CHECK,CHECK-HIDDEN
+
+class A {
+public:
+  ~A();
+} a;
+
+// CHECK-DEFAULT: @__dso_handle = global i8* bitcast (i8** @__dso_handle to i8*), align 8
+// CHECK-HIDDEN: @__dso_handle = hidden global i8* bitcast (i8** @__dso_handle to i8*), align 8
+// CHECK: define internal void @__cxx_global_var_init()
+// CHECK:   call i32 @__cxa_atexit({{.*}}, {{.*}}, i8* bitcast (i8** @__dso_handle to i8*))
+
+#ifdef HIDDEN
+void *__dso_handle __attribute__((__visibility__("hidden"))) = &__dso_handle;
+#else
+void *__dso_handle = &__dso_handle;
+#endif
+
+void use(void *);
+void use_dso_handle() {
+  use(__dso_handle);
+}
Index: clang/lib/CodeGen/CodeGenModule.cpp
===
--- clang/lib/CodeGen/CodeGenModule.cpp
+++ clang/lib/CodeGen/CodeGenModule.cpp
@@ -4284,7 +4284,7 @@
   OpenMPRuntime->emitTargetGlobalVariable(D))
 return;
 
-  llvm::Constant *Init = nullptr;
+  llvm::TrackingVH Init;
   bool NeedsGlobalCtor = false;
   bool NeedsGlobalDtor =
   D->needsDestruction(getContext()) == QualType::DK_cxx_destructor;
@@ -4330,9 +4330,8 @@
   } else {
 initializedGlobalDecl = GlobalDecl(D);
 emitter.emplace(*this);
-Init = emitter->tryEmitForInitializer(*InitDecl);
-
-if (!Init) {
+llvm::Constant *Initializer = emitter->tryEmitForInitializer(*InitDecl);
+if (!Initializer) {
   QualType T = InitExpr->getType();
   if (D->getType()->isReferenceType())
 T = D->getType();
@@ -4345,6 +4344,7 @@
 Init = llvm::UndefValue::get(getTypes().ConvertType(T));
   }
 } else {
+  Init = Initializer;
   // We don't need an initializer, so remove the entry for the delayed
   // initializer position (just in case this entry was delayed) if we
   // also don't need to register a destructor.
___

[PATCH] D101156: [Clang] Support a user-defined __dso_handle

2021-06-03 Thread Andrew Savonichev via Phabricator via cfe-commits
asavonic added a comment.

ping


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D101156

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


[PATCH] D98895: [X86][Draft] Disable long double type for -mno-x87 option

2021-05-27 Thread Andrew Savonichev via Phabricator via cfe-commits
asavonic updated this revision to Diff 348219.
asavonic added a comment.

- Disabled double or float return for x86 targets
- Refactored checks into a separate function.


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D98895

Files:
  clang/include/clang/Basic/DiagnosticSemaKinds.td
  clang/include/clang/Basic/TargetInfo.h
  clang/include/clang/Sema/Sema.h
  clang/lib/Basic/TargetInfo.cpp
  clang/lib/Basic/Targets/X86.cpp
  clang/lib/Basic/Targets/X86.h
  clang/lib/Sema/SemaChecking.cpp
  clang/lib/Sema/SemaDecl.cpp
  clang/lib/Sema/SemaExpr.cpp
  clang/test/Sema/x86-no-x87.c

Index: clang/test/Sema/x86-no-x87.c
===
--- /dev/null
+++ clang/test/Sema/x86-no-x87.c
@@ -0,0 +1,93 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s -triple x86_64-linux-gnu -target-feature -x87
+// RUN: %clang_cc1 -fsyntax-only -verify %s -triple i686-linux-gnu -target-feature -x87 -DRET_ERROR
+// RUN: %clang_cc1 -fsyntax-only -verify %s -triple x86_64-windows-msvc -target-feature -x87 -DNOERROR
+// RUN: %clang_cc1 -fsyntax-only -verify %s -triple x86_64-linux-gnu -DNOERROR
+
+#ifdef NOERROR
+// expected-no-diagnostics
+#endif
+
+typedef long double long_double;
+
+// Declaration is fine, unless it is called or defined.
+double decl(long_double x, long_double y);
+
+#ifndef NOERROR
+// expected-error@+3{{long double is not supported on this target}}
+// expected-error@+2{{long double is not supported on this target}}
+#endif
+double ld_args(long_double x, long_double y);
+
+long_double ld_ret(double x, double y);
+
+#ifdef RET_ERROR
+// expected-error@+4{{return value of type double is not supported on this target}}
+// expected-error@+2{{return value of type double is not supported on this target}}
+#endif
+double args(double x, double y) {
+  return ld_args(x, y);
+}
+
+#ifdef RET_ERROR
+// expected-error@+2{{return value of type double is not supported on this target}}
+#endif
+double ret1(double x, double y) {
+#ifndef NOERROR
+  // expected-error@+2{{long double is not supported on this target}}
+#endif
+  return ld_ret(x, y);
+}
+
+#ifdef RET_ERROR
+// expected-error@+2{{return value of type float is not supported on this target}}
+#endif
+const float ret2(float a, double b) {
+  return a * b;
+}
+
+#ifdef RET_ERROR
+// expected-error@+2{{return value of type double is not supported on this target}}
+#endif
+double binop(double x, double y) {
+#ifndef NOERROR
+  // expected-error@+2{{long double is not supported on this target}}
+#endif
+  double z = (long_double)x * (long_double)y;
+  return z;
+}
+
+void assign1(long_double *ret, double x) {
+#ifndef NOERROR
+  // expected-error@+2{{long double is not supported on this target}}
+#endif
+  *ret = x;
+}
+
+struct st_long_double {
+  long_double ld;
+};
+
+void assign2() {
+  struct st_long_double st;
+  st.ld = 0.42;
+}
+
+void assign3() {
+  struct st_long_double st;
+  st.ld = 42;
+}
+
+void assign4(double d) {
+  struct st_long_double st;
+#ifndef NOERROR
+  // expected-error@+2{{long double is not supported on this target}}
+#endif
+  st.ld = d;
+}
+
+void assign5() {
+#ifndef NOERROR
+  // expected-error@+2{{long double is not supported on this target}}
+#endif
+  long_double ld = 0.42;
+}
Index: clang/lib/Sema/SemaExpr.cpp
===
--- clang/lib/Sema/SemaExpr.cpp
+++ clang/lib/Sema/SemaExpr.cpp
@@ -14002,6 +14002,20 @@
 }
   }
 
+  // Allow assignment of a literal, because it compiles to just a
+  // store of a constant.
+  bool IsLiteralAssign = (Opc == BO_Assign) && (isa(RHSExpr) ||
+isa(RHSExpr));
+
+  if (!IsLiteralAssign) {
+if (CheckTargetTypeSupport(Context.getTargetInfo(), LHSExpr->getType(),
+   OpLoc, /*IsReturnType=*/false) ||
+CheckTargetTypeSupport(Context.getTargetInfo(), RHSExpr->getType(),
+   OpLoc, /*IsReturnType=*/false)) {
+  return ExprError();
+}
+  }
+
   switch (Opc) {
   case BO_Assign:
 ResultTy = CheckAssignmentOperands(LHS.get(), RHS, OpLoc, QualType());
@@ -14840,6 +14854,13 @@
   if (Opc != UO_AddrOf && Opc != UO_Deref)
 CheckArrayAccess(Input.get());
 
+  if (CheckTargetTypeSupport(Context.getTargetInfo(), resultType, OpLoc,
+ /*IsReturnType=*/false) ||
+  CheckTargetTypeSupport(Context.getTargetInfo(), InputExpr->getType(),
+ OpLoc, /*IsReturnType=*/false)) {
+return ExprError();
+  }
+
   auto *UO =
   UnaryOperator::Create(Context, Input.get(), Opc, resultType, VK, OK,
 OpLoc, CanOverflow, CurFPFeatureOverrides());
Index: clang/lib/Sema/SemaDecl.cpp
===
--- clang/lib/Sema/SemaDecl.cpp
+++ clang/lib/Sema/SemaDecl.cpp
@@ -7270,6 +7270,9 @@
 

[PATCH] D98895: [X86][Draft] Disable long double type for -mno-x87 option

2021-05-25 Thread Andrew Savonichev via Phabricator via cfe-commits
asavonic added inline comments.



Comment at: clang/test/Sema/x86-no-x87.c:2
+// RUN: %clang_cc1 -fsyntax-only -verify %s -triple x86_64-linux-gnu 
-target-feature -x87
+// RUN: %clang_cc1 -fsyntax-only -verify %s -triple i686-linux-gnu 
-target-feature -x87
+// RUN: %clang_cc1 -fsyntax-only -verify %s -triple x86_64-windows-msvc 
-target-feature -x87 -DNOERROR

pengfei wrote:
> Should i686 expect no error like GCC?
GCC seems to fallback to soft-float for i686 if -mno-80387 is used:

  long double orig(long double x, long double y)
  {
long double z = x + y;
if (z < 0.0)
  return z;
else
  return 0.0;
  }

i686-linux-gnu-gcc-8 -c -S -mno-80387 -O3:
  call  __addxf3@PLT
  [...]
  call  __ltxf2@PLT
  addl  $32, %esp
  testl %eax, %eax
  js.L3
  xorl  %esi, %esi
  xorl  %edi, %edi
  xorl  %ebp, %ebp
  .L3:
  addl  $12, %esp
  movl  %esi, %eax
  movl  %edi, %edx
  movl  %ebp, %ecx
  popl  %ebx
  popl  %esi
  popl  %edi
  popl  %ebp
  ret

This looks like a different ABI.
X87 instructions are not used, so no error is reported.



Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D98895

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


[PATCH] D98895: [X86][Draft] Disable long double type for -mno-x87 option

2021-05-24 Thread Andrew Savonichev via Phabricator via cfe-commits
asavonic updated this revision to Diff 347443.
asavonic added a comment.

Added LIT run lines for i686 and windows targets.


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D98895

Files:
  clang/include/clang/Basic/TargetInfo.h
  clang/lib/Basic/TargetInfo.cpp
  clang/lib/Basic/Targets/X86.cpp
  clang/lib/Basic/Targets/X86.h
  clang/lib/Sema/SemaChecking.cpp
  clang/lib/Sema/SemaDecl.cpp
  clang/lib/Sema/SemaExpr.cpp
  clang/test/Sema/x86-no-x87.c

Index: clang/test/Sema/x86-no-x87.c
===
--- /dev/null
+++ clang/test/Sema/x86-no-x87.c
@@ -0,0 +1,73 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s -triple x86_64-linux-gnu -target-feature -x87
+// RUN: %clang_cc1 -fsyntax-only -verify %s -triple i686-linux-gnu -target-feature -x87
+// RUN: %clang_cc1 -fsyntax-only -verify %s -triple x86_64-windows-msvc -target-feature -x87 -DNOERROR
+// RUN: %clang_cc1 -fsyntax-only -verify %s -triple x86_64-linux-gnu -DNOERROR
+
+#ifdef NOERROR
+// expected-no-diagnostics
+#endif
+
+typedef long double long_double;
+
+#ifndef NOERROR
+// expected-error@+3{{long double is not supported on this target}}
+// expected-error@+2{{long double is not supported on this target}}
+#endif
+double ld_args(long_double x, long_double y);
+
+long_double ld_ret(double x, double y);
+
+double args(double x, double y) {
+  return ld_args(x, y);
+}
+
+double ret(double x, double y) {
+#ifndef NOERROR
+  // expected-error@+2{{long double is not supported on this target}}
+#endif
+  return ld_ret(x, y);
+}
+
+double binop(double x, double y) {
+#ifndef NOERROR
+  // expected-error@+2{{long double is not supported on this target}}
+#endif
+  double z = (long_double)x * (long_double)y;
+  return z;
+}
+
+void assign1(long_double *ret, double x) {
+#ifndef NOERROR
+  // expected-error@+2{{long double is not supported on this target}}
+#endif
+  *ret = x;
+}
+
+struct st_long_double {
+  long_double ld;
+};
+
+void assign2() {
+  struct st_long_double st;
+  st.ld = 0.42;
+}
+
+void assign3() {
+  struct st_long_double st;
+  st.ld = 42;
+}
+
+void assign4(double d) {
+  struct st_long_double st;
+#ifndef NOERROR
+  // expected-error@+2{{long double is not supported on this target}}
+#endif
+  st.ld = d;
+}
+
+void assign5() {
+#ifndef NOERROR
+  // expected-error@+2{{long double is not supported on this target}}
+#endif
+  long_double ld = 0.42;
+}
Index: clang/lib/Sema/SemaExpr.cpp
===
--- clang/lib/Sema/SemaExpr.cpp
+++ clang/lib/Sema/SemaExpr.cpp
@@ -14002,6 +14002,26 @@
 }
   }
 
+  if (!Context.getTargetInfo().hasLongDoubleType()) {
+QualType LHSTy = LHSExpr->getType();
+QualType RHSTy = RHSExpr->getType();
+
+// Allow assignment of a literal, because it compiles to just a
+// store of a constant.
+bool IsLiteralAssign =
+(Opc == BO_Assign) &&
+(isa(RHSExpr) || isa(RHSExpr));
+
+bool HaveLongDoubleOp =
+(LHSTy.getCanonicalType() == Context.LongDoubleTy) ||
+(RHSTy.getCanonicalType() == Context.LongDoubleTy);
+
+if (HaveLongDoubleOp && !IsLiteralAssign) {
+  Diag(OpLoc, diag::err_type_unsupported) << "long double";
+  return ExprError();
+}
+  }
+
   switch (Opc) {
   case BO_Assign:
 ResultTy = CheckAssignmentOperands(LHS.get(), RHS, OpLoc, QualType());
@@ -14840,6 +14860,13 @@
   if (Opc != UO_AddrOf && Opc != UO_Deref)
 CheckArrayAccess(Input.get());
 
+  if (!Context.getTargetInfo().hasLongDoubleType() &&
+  (resultType.getCanonicalType() == Context.LongDoubleTy ||
+   InputExpr->getType().getCanonicalType() == Context.LongDoubleTy)) {
+Diag(OpLoc, diag::err_type_unsupported) << "long double";
+return ExprError();
+  }
+
   auto *UO =
   UnaryOperator::Create(Context, Input.get(), Opc, resultType, VK, OK,
 OpLoc, CanOverflow, CurFPFeatureOverrides());
Index: clang/lib/Sema/SemaDecl.cpp
===
--- clang/lib/Sema/SemaDecl.cpp
+++ clang/lib/Sema/SemaDecl.cpp
@@ -7270,6 +7270,11 @@
 }
   }
 
+  if (!Context.getTargetInfo().hasLongDoubleType() &&
+  NewVD->getType().getCanonicalType() == Context.LongDoubleTy) {
+Diag(NewVD->getLocation(), diag::err_type_unsupported) << "long double";
+  }
+
   // Handle attributes prior to checking for duplicates in MergeVarDecl
   ProcessDeclAttributes(S, NewVD, D);
 
@@ -14223,6 +14228,17 @@
   CheckParmsForFunctionDef(FD->parameters(),
/*CheckParameterNames=*/true);
 
+  if (!Context.getTargetInfo().hasLongDoubleType()) {
+if (ResultType.getCanonicalType() == Context.LongDoubleTy) {
+  Diag(FD->getLocation(), diag::err_type_unsupported) << "long double";
+}
+for (ParmVarDecl *Param : FD->parameters()) {
+  if (Param->getType().getCanonicalType() == 

[PATCH] D98895: [X86][Draft] Disable long double type for -mno-x87 option

2021-05-24 Thread Andrew Savonichev via Phabricator via cfe-commits
asavonic added inline comments.



Comment at: clang/test/Sema/x86-no-x87.c:48-61
+void assign2() {
+  struct st_long_double st;
+#ifndef NOERROR
+  // expected-error@+2{{long double is not supported on this target}}
+#endif
+  st.ld = 0.42;
+}

pengfei wrote:
> asavonic wrote:
> > pengfei wrote:
> > > These seems pass with GCC. https://godbolt.org/z/qM4nWhThx
> > Right. Assignment of a literal is compiled to just `mov` without any x87 
> > instructions, so it is not diagnosed by GCC. On the other hand, assignment 
> > of a variable does trigger the error:
> > 
> > void assign4(double d) {
> >   struct st_long_double st;
> >   st.ld = d; // error: long double is not supported on this target
> > }
> > 
> > We can update the patch to do the same for some cases, but it does not look 
> > very consistent, and makes assumptions on how the code is optimized and 
> > compiled.
> > 
> > GCC has an advantage here, because it emits the diagnostic at a lower level 
> > after at lease some optimizations are done. For example, the following code 
> > does not trigger an error for GCC because of inlining:
> > 
> > double get_const() {
> >   return 0.42;
> > }
> > void assign5(struct st_long_double *st) {
> >   st->ld = get_const();
> > }
> > 
> I see. Another concern is about the 32 bits. @LiuChen3 had tested in D100091 
> that GCC doesn't error for 32 bits. Do we need to consider it here?
Yes, it should be considered. Both x86 and x86_64 SysV ABI targets require x87 
to be used for long double. Other targets have different requirements for long 
double: double precision for Windows, double and quad precision for Android x86 
and x86_64 respectively.



Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D98895

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


[PATCH] D101156: [Clang] Support a user-defined __dso_handle

2021-05-24 Thread Andrew Savonichev via Phabricator via cfe-commits
asavonic added a comment.

I went ahead and implemented a fix for EmitGlobalVarDefinition. Please let me 
know what approach is preferable: Diff 339986 or Diff 347341.


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D101156

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


[PATCH] D101156: [Clang] Support a user-defined __dso_handle

2021-05-24 Thread Andrew Savonichev via Phabricator via cfe-commits
asavonic updated this revision to Diff 347341.
asavonic edited the summary of this revision.

Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D101156

Files:
  clang/lib/CodeGen/CodeGenModule.cpp
  clang/test/CodeGenCXX/dso-handle-custom.cpp


Index: clang/test/CodeGenCXX/dso-handle-custom.cpp
===
--- /dev/null
+++ clang/test/CodeGenCXX/dso-handle-custom.cpp
@@ -0,0 +1,23 @@
+// RUN: %clang_cc1 -triple x86_64-unknown-linux-gnu -emit-llvm -fexceptions %s 
-o - | FileCheck %s --check-prefixes CHECK,CHECK-DEFAULT
+// RUN: %clang_cc1 -triple x86_64-unknown-linux-gnu -emit-llvm -fexceptions %s 
-o - -DHIDDEN | FileCheck %s --check-prefixes CHECK,CHECK-HIDDEN
+
+class A {
+public:
+  ~A();
+} a;
+
+// CHECK-DEFAULT: @__dso_handle = global i8* bitcast (i8** @__dso_handle to 
i8*), align 8
+// CHECK-HIDDEN: @__dso_handle = hidden global i8* bitcast (i8** @__dso_handle 
to i8*), align 8
+// CHECK: define internal void @__cxx_global_var_init()
+// CHECK:   call i32 @__cxa_atexit({{.*}}, {{.*}}, i8* bitcast (i8** 
@__dso_handle to i8*))
+
+#ifdef HIDDEN
+void *__dso_handle __attribute__((__visibility__("hidden"))) = &__dso_handle;
+#else
+void *__dso_handle = &__dso_handle;
+#endif
+
+void use(void *);
+void use_dso_handle() {
+  use(__dso_handle);
+}
Index: clang/lib/CodeGen/CodeGenModule.cpp
===
--- clang/lib/CodeGen/CodeGenModule.cpp
+++ clang/lib/CodeGen/CodeGenModule.cpp
@@ -4337,6 +4337,23 @@
   }
 
   llvm::Type* InitType = Init->getType();
+
+  bool ReplaceInitWithGV = false;
+  llvm::GlobalValue *OrigEntry = GetGlobalValue(getMangledName(D));
+  if (Init == OrigEntry && OrigEntry->getValueType() != InitType) {
+// Type of the initializer does not match the type of the global -
+// GetAddrOfGlobalVar is going to recreate it, replace all uses of
+// the original entry and erase the original entry from the
+// module.
+//
+// However, if Init is an address of the global itself, then it is
+// not a use, and thus it will not be replaced. It will become a
+// dangling pointer after GetAddrOfGlobalVar. Replace it once we
+// get a new GV.
+//
+ReplaceInitWithGV = true;
+  }
+
   llvm::Constant *Entry =
   GetAddrOfGlobalVar(D, InitType, ForDefinition_t(!IsTentative));
 
@@ -4404,6 +4421,9 @@
 getCUDARuntime().handleVarRegistration(D, *GV);
   }
 
+  if (ReplaceInitWithGV)
+Init = llvm::ConstantExpr::getBitCast(GV, GV->getValueType());
+
   GV->setInitializer(Init);
   if (emitter)
 emitter->finalize(GV);


Index: clang/test/CodeGenCXX/dso-handle-custom.cpp
===
--- /dev/null
+++ clang/test/CodeGenCXX/dso-handle-custom.cpp
@@ -0,0 +1,23 @@
+// RUN: %clang_cc1 -triple x86_64-unknown-linux-gnu -emit-llvm -fexceptions %s -o - | FileCheck %s --check-prefixes CHECK,CHECK-DEFAULT
+// RUN: %clang_cc1 -triple x86_64-unknown-linux-gnu -emit-llvm -fexceptions %s -o - -DHIDDEN | FileCheck %s --check-prefixes CHECK,CHECK-HIDDEN
+
+class A {
+public:
+  ~A();
+} a;
+
+// CHECK-DEFAULT: @__dso_handle = global i8* bitcast (i8** @__dso_handle to i8*), align 8
+// CHECK-HIDDEN: @__dso_handle = hidden global i8* bitcast (i8** @__dso_handle to i8*), align 8
+// CHECK: define internal void @__cxx_global_var_init()
+// CHECK:   call i32 @__cxa_atexit({{.*}}, {{.*}}, i8* bitcast (i8** @__dso_handle to i8*))
+
+#ifdef HIDDEN
+void *__dso_handle __attribute__((__visibility__("hidden"))) = &__dso_handle;
+#else
+void *__dso_handle = &__dso_handle;
+#endif
+
+void use(void *);
+void use_dso_handle() {
+  use(__dso_handle);
+}
Index: clang/lib/CodeGen/CodeGenModule.cpp
===
--- clang/lib/CodeGen/CodeGenModule.cpp
+++ clang/lib/CodeGen/CodeGenModule.cpp
@@ -4337,6 +4337,23 @@
   }
 
   llvm::Type* InitType = Init->getType();
+
+  bool ReplaceInitWithGV = false;
+  llvm::GlobalValue *OrigEntry = GetGlobalValue(getMangledName(D));
+  if (Init == OrigEntry && OrigEntry->getValueType() != InitType) {
+// Type of the initializer does not match the type of the global -
+// GetAddrOfGlobalVar is going to recreate it, replace all uses of
+// the original entry and erase the original entry from the
+// module.
+//
+// However, if Init is an address of the global itself, then it is
+// not a use, and thus it will not be replaced. It will become a
+// dangling pointer after GetAddrOfGlobalVar. Replace it once we
+// get a new GV.
+//
+ReplaceInitWithGV = true;
+  }
+
   llvm::Constant *Entry =
   GetAddrOfGlobalVar(D, InitType, ForDefinition_t(!IsTentative));
 
@@ -4404,6 +4421,9 @@
 getCUDARuntime().handleVarRegistration(D, *GV);
   }
 
+  if (ReplaceInitWithGV)
+Init = llvm::ConstantExpr::getBitCast(GV, 

[PATCH] D98895: [X86][Draft] Disable long double type for -mno-x87 option

2021-05-19 Thread Andrew Savonichev via Phabricator via cfe-commits
asavonic added inline comments.



Comment at: clang/test/Sema/x86-no-x87.c:48-61
+void assign2() {
+  struct st_long_double st;
+#ifndef NOERROR
+  // expected-error@+2{{long double is not supported on this target}}
+#endif
+  st.ld = 0.42;
+}

pengfei wrote:
> These seems pass with GCC. https://godbolt.org/z/qM4nWhThx
Right. Assignment of a literal is compiled to just `mov` without any x87 
instructions, so it is not diagnosed by GCC. On the other hand, assignment of a 
variable does trigger the error:

void assign4(double d) {
  struct st_long_double st;
  st.ld = d; // error: long double is not supported on this target
}

We can update the patch to do the same for some cases, but it does not look 
very consistent, and makes assumptions on how the code is optimized and 
compiled.

GCC has an advantage here, because it emits the diagnostic at a lower level 
after at lease some optimizations are done. For example, the following code 
does not trigger an error for GCC because of inlining:

double get_const() {
  return 0.42;
}
void assign5(struct st_long_double *st) {
  st->ld = get_const();
}



Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D98895

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


[PATCH] D98895: [X86][Draft] Disable long double type for -mno-x87 option

2021-05-18 Thread Andrew Savonichev via Phabricator via cfe-commits
asavonic added a comment.

ping


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D98895

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


[PATCH] D101156: [Clang] Support a user-defined __dso_handle

2021-05-12 Thread Andrew Savonichev via Phabricator via cfe-commits
asavonic added a comment.

In D101156#2724789 , @rjmccall wrote:

> What's the crash exactly/  Is IRGen just unhappy about processing the user 
> definition when we've generated a declaration with a different type?  Because 
> we're already supposed to be being cautious about this.

Hi John. Sorry for the late reply.

  class a {
  public:
~a();
  } b;
  void *__dso_handle = &__dso_handle;

This code code causes a crash because the compiler first generates a
__dso_handle with i8 type:

  @__dso_handle = external dso_local global i8

... and then reaches the explicit definition of it with a pointer type and a
pointer initializer, and tries to generate this instead:

  @__dso_handle = hidden global i8* bitcast (i8** @__dso_handle to i8*), align 8

Since __dso_handle already exists in the module, it must be replaced because the
initializer has an incompatible type.

There is indeed some handling for this case in EmitGlobalVarDefinition, but it
does not work correctly when the initializer is a pointer to the variable
itself. Specifically, the Init variable in EmitGlobalVarDefinition becomes
stale:

  p Init->dump()
   = hidden global i8 

The current patch avoids this problem by having two distinct globals, but maybe
it is better to fix EmitGlobalVarDefinition instead? Is it supposed to handle
such case?


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D101156

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


[PATCH] D100591: [Clang][AArch64] Disable rounding of return values for AArch64

2021-05-04 Thread Andrew Savonichev via Phabricator via cfe-commits
This revision was automatically updated to reflect the committed changes.
Closed by commit rGb451ecd86e13: [Clang][AArch64] Disable rounding of return 
values for AArch64 (authored by asavonic).

Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D100591

Files:
  clang/lib/CodeGen/TargetInfo.cpp
  clang/test/CodeGen/aarch64-varargs.c
  clang/test/CodeGen/arm64-arguments.c
  clang/test/CodeGen/arm64-microsoft-arguments.cpp
  clang/test/CodeGen/attr-noundef.cpp
  clang/test/CodeGenCXX/microsoft-abi-sret-and-byval.cpp
  clang/test/CodeGenCXX/trivial_abi.cpp

Index: clang/test/CodeGenCXX/trivial_abi.cpp
===
--- clang/test/CodeGenCXX/trivial_abi.cpp
+++ clang/test/CodeGenCXX/trivial_abi.cpp
@@ -198,12 +198,11 @@
   testReturnLarge();
 }
 
-// CHECK: define{{.*}} i64 @_Z20testReturnHasTrivialv()
+// CHECK: define{{.*}} i32 @_Z20testReturnHasTrivialv()
 // CHECK: %[[RETVAL:.*]] = alloca %[[STRUCT_TRIVIAL:.*]], align 4
 // CHECK: %[[COERCE_DIVE:.*]] = getelementptr inbounds %[[STRUCT_TRIVIAL]], %[[STRUCT_TRIVIAL]]* %[[RETVAL]], i32 0, i32 0
 // CHECK: %[[V0:.*]] = load i32, i32* %[[COERCE_DIVE]], align 4
-// CHECK: %[[COERCE_VAL_II:.*]] = zext i32 %[[V0]] to i64
-// CHECK: ret i64 %[[COERCE_VAL_II]]
+// CHECK: ret i32 %[[V0]]
 // CHECK: }
 
 Trivial testReturnHasTrivial() {
Index: clang/test/CodeGenCXX/microsoft-abi-sret-and-byval.cpp
===
--- clang/test/CodeGenCXX/microsoft-abi-sret-and-byval.cpp
+++ clang/test/CodeGenCXX/microsoft-abi-sret-and-byval.cpp
@@ -87,7 +87,7 @@
 // LINUX-LABEL: define{{.*}} void @_Z12small_returnv(%struct.Small* noalias sret(%struct.Small) align 4 %agg.result)
 // WIN32: define dso_local i32 @"?small_return@@YA?AUSmall@@XZ"()
 // WIN64: define dso_local i32 @"?small_return@@YA?AUSmall@@XZ"()
-// WOA64: define dso_local i64 @"?small_return@@YA?AUSmall@@XZ"()
+// WOA64: define dso_local i32 @"?small_return@@YA?AUSmall@@XZ"()
 
 Medium medium_return() { return Medium(); }
 // LINUX-LABEL: define{{.*}} void @_Z13medium_returnv(%struct.Medium* noalias sret(%struct.Medium) align 4 %agg.result)
Index: clang/test/CodeGen/attr-noundef.cpp
===
--- clang/test/CodeGen/attr-noundef.cpp
+++ clang/test/CodeGen/attr-noundef.cpp
@@ -11,7 +11,7 @@
 Trivial ret_trivial() { return {}; }
 void pass_trivial(Trivial e) {}
 // CHECK-INTEL: [[DEFINE:define( dso_local)?]] i32 @{{.*}}ret_trivial
-// CHECK-AARCH: [[DEFINE:define( dso_local)?]] i64 @{{.*}}ret_trivial
+// CHECK-AARCH: [[DEFINE:define( dso_local)?]] i32 @{{.*}}ret_trivial
 // CHECK-INTEL: [[DEFINE]] void @{{.*}}pass_trivial{{.*}}(i32 %
 // CHECK-AARCH: [[DEFINE]] void @{{.*}}pass_trivial{{.*}}(i64 %
 
@@ -43,7 +43,7 @@
 Trivial ret_trivial() { return {}; }
 void pass_trivial(Trivial e) {}
 // CHECK-INTEL: [[DEFINE]] i32 @{{.*}}ret_trivial
-// CHECK-AARCH: [[DEFINE]] i64 @{{.*}}ret_trivial
+// CHECK-AARCH: [[DEFINE]] i32 @{{.*}}ret_trivial
 // CHECK-INTEL: [[DEFINE]] void @{{.*}}pass_trivial{{.*}}(i32 %
 // CHECK-AARCH: [[DEFINE]] void @{{.*}}pass_trivial{{.*}}(i64 %
 
Index: clang/test/CodeGen/arm64-microsoft-arguments.cpp
===
--- clang/test/CodeGen/arm64-microsoft-arguments.cpp
+++ clang/test/CodeGen/arm64-microsoft-arguments.cpp
@@ -104,8 +104,8 @@
 
 // Pass and return an object with a non-trivial explicitly defaulted constructor
 // (passed directly, returned directly)
-// CHECK: define {{.*}} i64 @"?f6@@YA?AUS6@@XZ"()
-// CHECK: call i64 {{.*}}func6{{.*}}(i64 {{.*}})
+// CHECK: define {{.*}} i8 @"?f6@@YA?AUS6@@XZ"()
+// CHECK: call i8 {{.*}}func6{{.*}}(i64 {{.*}})
 struct S6a {
   S6a();
 };
@@ -123,8 +123,8 @@
 
 // Pass and return an object with a non-trivial implicitly defaulted constructor
 // (passed directly, returned directly)
-// CHECK: define {{.*}} i64 @"?f7@@YA?AUS7@@XZ"()
-// CHECK: call i64 {{.*}}func7{{.*}}(i64 {{.*}})
+// CHECK: define {{.*}} i8 @"?f7@@YA?AUS7@@XZ"()
+// CHECK: call i8 {{.*}}func7{{.*}}(i64 {{.*}})
 struct S7 {
   S6a x;
 };
Index: clang/test/CodeGen/arm64-arguments.c
===
--- clang/test/CodeGen/arm64-arguments.c
+++ clang/test/CodeGen/arm64-arguments.c
@@ -1,33 +1,41 @@
-// RUN: %clang_cc1 -triple arm64-apple-ios7 -target-feature +neon -target-abi darwinpcs -ffreestanding -emit-llvm -w -o - %s | FileCheck %s
+// RUN: %clang_cc1 -triple arm64-apple-ios7 -target-feature +neon -target-abi darwinpcs -ffreestanding -emit-llvm -w -o - %s | FileCheck %s --check-prefixes=CHECK,CHECK-LE
+// RUN: %clang_cc1 -triple aarch64_be-none-linux-gnu -target-feature +neon -target-abi darwinpcs -ffreestanding -emit-llvm -w -o - %s | FileCheck %s --check-prefixes=CHECK,CHECK-BE
 
 // CHECK: define{{.*}} signext i8 @f0()
 char f0(void) {
   

[PATCH] D98895: [X86][Draft] Disable long double type for -mno-x87 option

2021-04-26 Thread Andrew Savonichev via Phabricator via cfe-commits
asavonic added a comment.

The option was added in D19658  and D13979 
, but I'm not sure how it is supposed to work 
for SystemV ABI.
GCC emits an error if long double type is used with -mno-x87: "test.c:37:1: 
error: x87 register return with x87 disabled".

Added reviewers of the original patches. Please let me know if this patch makes 
sense, or we should do something else to avoid the crash.


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D98895

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


[PATCH] D100591: [Clang][AArch64] Disable rounding of return values for AArch64

2021-04-26 Thread Andrew Savonichev via Phabricator via cfe-commits
asavonic updated this revision to Diff 340517.
asavonic added a comment.

Keep rounding of return values for big-endian targets.


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D100591

Files:
  clang/lib/CodeGen/TargetInfo.cpp
  clang/test/CodeGen/aarch64-varargs.c
  clang/test/CodeGen/arm64-arguments.c
  clang/test/CodeGen/arm64-microsoft-arguments.cpp
  clang/test/CodeGen/attr-noundef.cpp
  clang/test/CodeGenCXX/microsoft-abi-sret-and-byval.cpp
  clang/test/CodeGenCXX/trivial_abi.cpp

Index: clang/test/CodeGenCXX/trivial_abi.cpp
===
--- clang/test/CodeGenCXX/trivial_abi.cpp
+++ clang/test/CodeGenCXX/trivial_abi.cpp
@@ -198,12 +198,11 @@
   testReturnLarge();
 }
 
-// CHECK: define{{.*}} i64 @_Z20testReturnHasTrivialv()
+// CHECK: define{{.*}} i32 @_Z20testReturnHasTrivialv()
 // CHECK: %[[RETVAL:.*]] = alloca %[[STRUCT_TRIVIAL:.*]], align 4
 // CHECK: %[[COERCE_DIVE:.*]] = getelementptr inbounds %[[STRUCT_TRIVIAL]], %[[STRUCT_TRIVIAL]]* %[[RETVAL]], i32 0, i32 0
 // CHECK: %[[V0:.*]] = load i32, i32* %[[COERCE_DIVE]], align 4
-// CHECK: %[[COERCE_VAL_II:.*]] = zext i32 %[[V0]] to i64
-// CHECK: ret i64 %[[COERCE_VAL_II]]
+// CHECK: ret i32 %[[V0]]
 // CHECK: }
 
 Trivial testReturnHasTrivial() {
Index: clang/test/CodeGenCXX/microsoft-abi-sret-and-byval.cpp
===
--- clang/test/CodeGenCXX/microsoft-abi-sret-and-byval.cpp
+++ clang/test/CodeGenCXX/microsoft-abi-sret-and-byval.cpp
@@ -87,7 +87,7 @@
 // LINUX-LABEL: define{{.*}} void @_Z12small_returnv(%struct.Small* noalias sret(%struct.Small) align 4 %agg.result)
 // WIN32: define dso_local i32 @"?small_return@@YA?AUSmall@@XZ"()
 // WIN64: define dso_local i32 @"?small_return@@YA?AUSmall@@XZ"()
-// WOA64: define dso_local i64 @"?small_return@@YA?AUSmall@@XZ"()
+// WOA64: define dso_local i32 @"?small_return@@YA?AUSmall@@XZ"()
 
 Medium medium_return() { return Medium(); }
 // LINUX-LABEL: define{{.*}} void @_Z13medium_returnv(%struct.Medium* noalias sret(%struct.Medium) align 4 %agg.result)
Index: clang/test/CodeGen/attr-noundef.cpp
===
--- clang/test/CodeGen/attr-noundef.cpp
+++ clang/test/CodeGen/attr-noundef.cpp
@@ -11,7 +11,7 @@
 Trivial ret_trivial() { return {}; }
 void pass_trivial(Trivial e) {}
 // CHECK-INTEL: [[DEFINE:define( dso_local)?]] i32 @{{.*}}ret_trivial
-// CHECK-AARCH: [[DEFINE:define( dso_local)?]] i64 @{{.*}}ret_trivial
+// CHECK-AARCH: [[DEFINE:define( dso_local)?]] i32 @{{.*}}ret_trivial
 // CHECK-INTEL: [[DEFINE]] void @{{.*}}pass_trivial{{.*}}(i32 %
 // CHECK-AARCH: [[DEFINE]] void @{{.*}}pass_trivial{{.*}}(i64 %
 
@@ -43,7 +43,7 @@
 Trivial ret_trivial() { return {}; }
 void pass_trivial(Trivial e) {}
 // CHECK-INTEL: [[DEFINE]] i32 @{{.*}}ret_trivial
-// CHECK-AARCH: [[DEFINE]] i64 @{{.*}}ret_trivial
+// CHECK-AARCH: [[DEFINE]] i32 @{{.*}}ret_trivial
 // CHECK-INTEL: [[DEFINE]] void @{{.*}}pass_trivial{{.*}}(i32 %
 // CHECK-AARCH: [[DEFINE]] void @{{.*}}pass_trivial{{.*}}(i64 %
 
Index: clang/test/CodeGen/arm64-microsoft-arguments.cpp
===
--- clang/test/CodeGen/arm64-microsoft-arguments.cpp
+++ clang/test/CodeGen/arm64-microsoft-arguments.cpp
@@ -104,8 +104,8 @@
 
 // Pass and return an object with a non-trivial explicitly defaulted constructor
 // (passed directly, returned directly)
-// CHECK: define {{.*}} i64 @"?f6@@YA?AUS6@@XZ"()
-// CHECK: call i64 {{.*}}func6{{.*}}(i64 {{.*}})
+// CHECK: define {{.*}} i8 @"?f6@@YA?AUS6@@XZ"()
+// CHECK: call i8 {{.*}}func6{{.*}}(i64 {{.*}})
 struct S6a {
   S6a();
 };
@@ -123,8 +123,8 @@
 
 // Pass and return an object with a non-trivial implicitly defaulted constructor
 // (passed directly, returned directly)
-// CHECK: define {{.*}} i64 @"?f7@@YA?AUS7@@XZ"()
-// CHECK: call i64 {{.*}}func7{{.*}}(i64 {{.*}})
+// CHECK: define {{.*}} i8 @"?f7@@YA?AUS7@@XZ"()
+// CHECK: call i8 {{.*}}func7{{.*}}(i64 {{.*}})
 struct S7 {
   S6a x;
 };
Index: clang/test/CodeGen/arm64-arguments.c
===
--- clang/test/CodeGen/arm64-arguments.c
+++ clang/test/CodeGen/arm64-arguments.c
@@ -1,33 +1,41 @@
-// RUN: %clang_cc1 -triple arm64-apple-ios7 -target-feature +neon -target-abi darwinpcs -ffreestanding -emit-llvm -w -o - %s | FileCheck %s
+// RUN: %clang_cc1 -triple arm64-apple-ios7 -target-feature +neon -target-abi darwinpcs -ffreestanding -emit-llvm -w -o - %s | FileCheck %s --check-prefixes=CHECK,CHECK-LE
+// RUN: %clang_cc1 -triple aarch64_be-none-linux-gnu -target-feature +neon -target-abi darwinpcs -ffreestanding -emit-llvm -w -o - %s | FileCheck %s --check-prefixes=CHECK,CHECK-BE
 
 // CHECK: define{{.*}} signext i8 @f0()
 char f0(void) {
   return 0;
 }
 
-// Struct as return type. Aggregates <= 16 bytes 

[PATCH] D100591: [Clang][AArch64] Disable rounding of return values for AArch64

2021-04-26 Thread Andrew Savonichev via Phabricator via cfe-commits
asavonic added a comment.

In D100591#2711433 , @t.p.northover 
wrote:

> On big-endian targets the rounding up to 64-bits (specified in the AAPCS) is 
> significant; it means that structs get passed in the high bits of `x0` rather 
> than low. E.g. https://godbolt.org/z/6v36oexsW. I think this patch would 
> break that.

Thanks a lot! I've disabled the change for big-endian AArch64 targets.


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D100591

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


[PATCH] D101156: [Clang] Support a user-defined __dso_handle

2021-04-23 Thread Andrew Savonichev via Phabricator via cfe-commits
asavonic added a comment.

John, can you please review this patch?
I originally wanted to add a diagnostic to prevent the crash in CG (PR49198), 
but the case seems easy enough to support.


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D101156

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


[PATCH] D101156: [Clang] Support a user-defined __dso_handle

2021-04-23 Thread Andrew Savonichev via Phabricator via cfe-commits
asavonic created this revision.
asavonic requested review of this revision.
Herald added a project: clang.
Herald added a subscriber: cfe-commits.

This fixes PR49198: Wrong usage of __dso_handle in user code leads to a compiler
crash.

`__dso_handle` variable is now created with a prefix to avoid a conflict with
the user-defined one which can be emitted later. Once all globals are emitted,
it is renamed back or replaced with a user-defined `__dso_handle`.


Repository:
  rG LLVM Github Monorepo

https://reviews.llvm.org/D101156

Files:
  clang/lib/CodeGen/ItaniumCXXABI.cpp
  clang/test/CodeGenCXX/dso-handle-custom.cpp


Index: clang/test/CodeGenCXX/dso-handle-custom.cpp
===
--- /dev/null
+++ clang/test/CodeGenCXX/dso-handle-custom.cpp
@@ -0,0 +1,17 @@
+// RUN: %clang_cc1 -triple x86_64-unknown-linux-gnu -emit-llvm -fexceptions %s 
-o - | FileCheck %s
+
+class A {
+public:
+  ~A();
+} a;
+
+// CHECK: @__dso_handle = hidden global i8* bitcast (i8** @__dso_handle to 
i8*), align 8
+// CHECK: define internal void @__cxx_global_var_init()
+// CHECK:   call i32 @__cxa_atexit({{.*}}, {{.*}}, i8* bitcast (i8** 
@__dso_handle to i8*))
+
+void *__dso_handle = &__dso_handle;
+
+void use(void *);
+void use_dso_handle() {
+  use(__dso_handle);
+}
Index: clang/lib/CodeGen/ItaniumCXXABI.cpp
===
--- clang/lib/CodeGen/ItaniumCXXABI.cpp
+++ clang/lib/CodeGen/ItaniumCXXABI.cpp
@@ -2531,7 +2531,7 @@
 
   // Create a variable that binds the atexit to this shared object.
   llvm::Constant *handle =
-  CGF.CGM.CreateRuntimeVariable(CGF.Int8Ty, "__dso_handle");
+  CGF.CGM.CreateRuntimeVariable(CGF.Int8Ty, "$__dso_handle");
   auto *GV = cast(handle->stripPointerCasts());
   GV->setVisibility(llvm::GlobalValue::HiddenVisibility);
 
@@ -2685,6 +2685,26 @@
 
   if (getCXXABI().useSinitAndSterm())
 unregisterGlobalDtorsWithUnAtExit();
+
+  // Prefer user-defined __dso_handle over the compiler generated one
+  if (llvm::GlobalValue *GeneratedDSOHandle = GetGlobalValue("$__dso_handle")) 
{
+llvm::GlobalValue *CustomDSOHandle = GetGlobalValue("__dso_handle");
+if (!CustomDSOHandle) {
+  GeneratedDSOHandle->setName("__dso_handle");
+} else {
+  if (!isa(CustomDSOHandle))
+llvm_unreachable("__dso_handle must be a global variable");
+
+  setDSOLocal(CustomDSOHandle);
+  CustomDSOHandle->setLinkage(llvm::GlobalValue::ExternalLinkage);
+  CustomDSOHandle->setVisibility(llvm::GlobalValue::HiddenVisibility);
+
+  llvm::Constant *DSOHandle = llvm::ConstantExpr::getBitCast(
+  CustomDSOHandle, GeneratedDSOHandle->getType());
+  GeneratedDSOHandle->replaceAllUsesWith(DSOHandle);
+  GeneratedDSOHandle->eraseFromParent();
+}
+  }
 }
 
 /// Register a global destructor as best as we know how.


Index: clang/test/CodeGenCXX/dso-handle-custom.cpp
===
--- /dev/null
+++ clang/test/CodeGenCXX/dso-handle-custom.cpp
@@ -0,0 +1,17 @@
+// RUN: %clang_cc1 -triple x86_64-unknown-linux-gnu -emit-llvm -fexceptions %s -o - | FileCheck %s
+
+class A {
+public:
+  ~A();
+} a;
+
+// CHECK: @__dso_handle = hidden global i8* bitcast (i8** @__dso_handle to i8*), align 8
+// CHECK: define internal void @__cxx_global_var_init()
+// CHECK:   call i32 @__cxa_atexit({{.*}}, {{.*}}, i8* bitcast (i8** @__dso_handle to i8*))
+
+void *__dso_handle = &__dso_handle;
+
+void use(void *);
+void use_dso_handle() {
+  use(__dso_handle);
+}
Index: clang/lib/CodeGen/ItaniumCXXABI.cpp
===
--- clang/lib/CodeGen/ItaniumCXXABI.cpp
+++ clang/lib/CodeGen/ItaniumCXXABI.cpp
@@ -2531,7 +2531,7 @@
 
   // Create a variable that binds the atexit to this shared object.
   llvm::Constant *handle =
-  CGF.CGM.CreateRuntimeVariable(CGF.Int8Ty, "__dso_handle");
+  CGF.CGM.CreateRuntimeVariable(CGF.Int8Ty, "$__dso_handle");
   auto *GV = cast(handle->stripPointerCasts());
   GV->setVisibility(llvm::GlobalValue::HiddenVisibility);
 
@@ -2685,6 +2685,26 @@
 
   if (getCXXABI().useSinitAndSterm())
 unregisterGlobalDtorsWithUnAtExit();
+
+  // Prefer user-defined __dso_handle over the compiler generated one
+  if (llvm::GlobalValue *GeneratedDSOHandle = GetGlobalValue("$__dso_handle")) {
+llvm::GlobalValue *CustomDSOHandle = GetGlobalValue("__dso_handle");
+if (!CustomDSOHandle) {
+  GeneratedDSOHandle->setName("__dso_handle");
+} else {
+  if (!isa(CustomDSOHandle))
+llvm_unreachable("__dso_handle must be a global variable");
+
+  setDSOLocal(CustomDSOHandle);
+  CustomDSOHandle->setLinkage(llvm::GlobalValue::ExternalLinkage);
+  CustomDSOHandle->setVisibility(llvm::GlobalValue::HiddenVisibility);
+
+  llvm::Constant *DSOHandle = llvm::ConstantExpr::getBitCast(
+  CustomDSOHandle, GeneratedDSOHandle->getType());
+  

[PATCH] D100591: [Clang][AArch64] Disable rounding of return values for AArch64

2021-04-22 Thread Andrew Savonichev via Phabricator via cfe-commits
asavonic added a comment.

Ping.
Please let me know if the patch is acceptable for AArch64, or something else 
should be done to avoid overhead from rounding of return values.


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D100591

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


[PATCH] D100591: [Clang][AArch64] Disable rounding of return values for AArch64

2021-04-15 Thread Andrew Savonichev via Phabricator via cfe-commits
asavonic added a comment.

In D100591#2692599 , @rjmccall wrote:

> I think the right thing to do here is to recognize generally that we're 
> emitting a mandatory tail call, and so suppress *all* the normal 
> transformations on the return value.

I assume it can be tricky to detect such call. The final decision (tail call vs 
normal call) is made before instruction selection, after all LLVM IR 
optimization passes. So we can miss tail calls that are not obvious on 
non-optimized code, or get false-positive results for calls that a backend 
decides to emit as normal calls.

In any case, this patch can be useful not only for tail calls: `trunc + zext` 
sequence generated to round a return value can be problematic for other cases 
as well.


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D100591

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


[PATCH] D100591: [Clang][AArch64] Disable rounding of return values for AArch64

2021-04-15 Thread Andrew Savonichev via Phabricator via cfe-commits
asavonic added inline comments.



Comment at: clang/test/CodeGen/arm64-arguments.c:53
 
-// CHECK: define{{.*}} i64 @f12()
+// CHECK: define{{.*}} i24 @f11_packed()
+struct s11_packed { char c; short s } __attribute__((packed));

I'm not sure if `i24` here is a problem or not. Let me know if we need to 
handle this differently.


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D100591

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


[PATCH] D100591: [Clang][AArch64] Disable rounding of return values for AArch64

2021-04-15 Thread Andrew Savonichev via Phabricator via cfe-commits
asavonic created this revision.
asavonic added reviewers: rjmccall, dmgreen, t.p.northover, ostannard, 
sdesmalen, momchil.velikov, SjoerdMeijer.
Herald added subscribers: mstorsjo, danielkiss, kristof.beyls.
asavonic requested review of this revision.
Herald added a project: clang.
Herald added a subscriber: cfe-commits.

If a return value is explicitly rounded to 64 bits, an additional
`zext` instruction is emitted, and in some cases it prevents tail call
optimization.

As discussed in D100225 , this rounding is 
not necessary and can be
disabled.


Repository:
  rG LLVM Github Monorepo

https://reviews.llvm.org/D100591

Files:
  clang/lib/CodeGen/TargetInfo.cpp
  clang/test/CodeGen/aarch64-varargs.c
  clang/test/CodeGen/arm64-arguments.c
  clang/test/CodeGen/arm64-microsoft-arguments.cpp
  clang/test/CodeGen/attr-noundef.cpp
  clang/test/CodeGenCXX/microsoft-abi-sret-and-byval.cpp
  clang/test/CodeGenCXX/trivial_abi.cpp

Index: clang/test/CodeGenCXX/trivial_abi.cpp
===
--- clang/test/CodeGenCXX/trivial_abi.cpp
+++ clang/test/CodeGenCXX/trivial_abi.cpp
@@ -198,12 +198,11 @@
   testReturnLarge();
 }
 
-// CHECK: define{{.*}} i64 @_Z20testReturnHasTrivialv()
+// CHECK: define{{.*}} i32 @_Z20testReturnHasTrivialv()
 // CHECK: %[[RETVAL:.*]] = alloca %[[STRUCT_TRIVIAL:.*]], align 4
 // CHECK: %[[COERCE_DIVE:.*]] = getelementptr inbounds %[[STRUCT_TRIVIAL]], %[[STRUCT_TRIVIAL]]* %[[RETVAL]], i32 0, i32 0
 // CHECK: %[[V0:.*]] = load i32, i32* %[[COERCE_DIVE]], align 4
-// CHECK: %[[COERCE_VAL_II:.*]] = zext i32 %[[V0]] to i64
-// CHECK: ret i64 %[[COERCE_VAL_II]]
+// CHECK: ret i32 %[[V0]]
 // CHECK: }
 
 Trivial testReturnHasTrivial() {
Index: clang/test/CodeGenCXX/microsoft-abi-sret-and-byval.cpp
===
--- clang/test/CodeGenCXX/microsoft-abi-sret-and-byval.cpp
+++ clang/test/CodeGenCXX/microsoft-abi-sret-and-byval.cpp
@@ -87,7 +87,7 @@
 // LINUX-LABEL: define{{.*}} void @_Z12small_returnv(%struct.Small* noalias sret(%struct.Small) align 4 %agg.result)
 // WIN32: define dso_local i32 @"?small_return@@YA?AUSmall@@XZ"()
 // WIN64: define dso_local i32 @"?small_return@@YA?AUSmall@@XZ"()
-// WOA64: define dso_local i64 @"?small_return@@YA?AUSmall@@XZ"()
+// WOA64: define dso_local i32 @"?small_return@@YA?AUSmall@@XZ"()
 
 Medium medium_return() { return Medium(); }
 // LINUX-LABEL: define{{.*}} void @_Z13medium_returnv(%struct.Medium* noalias sret(%struct.Medium) align 4 %agg.result)
Index: clang/test/CodeGen/attr-noundef.cpp
===
--- clang/test/CodeGen/attr-noundef.cpp
+++ clang/test/CodeGen/attr-noundef.cpp
@@ -11,7 +11,7 @@
 Trivial ret_trivial() { return {}; }
 void pass_trivial(Trivial e) {}
 // CHECK-INTEL: [[DEFINE:define( dso_local)?]] i32 @{{.*}}ret_trivial
-// CHECK-AARCH: [[DEFINE:define( dso_local)?]] i64 @{{.*}}ret_trivial
+// CHECK-AARCH: [[DEFINE:define( dso_local)?]] i32 @{{.*}}ret_trivial
 // CHECK-INTEL: [[DEFINE]] void @{{.*}}pass_trivial{{.*}}(i32 %
 // CHECK-AARCH: [[DEFINE]] void @{{.*}}pass_trivial{{.*}}(i64 %
 
@@ -43,7 +43,7 @@
 Trivial ret_trivial() { return {}; }
 void pass_trivial(Trivial e) {}
 // CHECK-INTEL: [[DEFINE]] i32 @{{.*}}ret_trivial
-// CHECK-AARCH: [[DEFINE]] i64 @{{.*}}ret_trivial
+// CHECK-AARCH: [[DEFINE]] i32 @{{.*}}ret_trivial
 // CHECK-INTEL: [[DEFINE]] void @{{.*}}pass_trivial{{.*}}(i32 %
 // CHECK-AARCH: [[DEFINE]] void @{{.*}}pass_trivial{{.*}}(i64 %
 
Index: clang/test/CodeGen/arm64-microsoft-arguments.cpp
===
--- clang/test/CodeGen/arm64-microsoft-arguments.cpp
+++ clang/test/CodeGen/arm64-microsoft-arguments.cpp
@@ -104,8 +104,8 @@
 
 // Pass and return an object with a non-trivial explicitly defaulted constructor
 // (passed directly, returned directly)
-// CHECK: define {{.*}} i64 @"?f6@@YA?AUS6@@XZ"()
-// CHECK: call i64 {{.*}}func6{{.*}}(i64 {{.*}})
+// CHECK: define {{.*}} i8 @"?f6@@YA?AUS6@@XZ"()
+// CHECK: call i8 {{.*}}func6{{.*}}(i64 {{.*}})
 struct S6a {
   S6a();
 };
@@ -123,8 +123,8 @@
 
 // Pass and return an object with a non-trivial implicitly defaulted constructor
 // (passed directly, returned directly)
-// CHECK: define {{.*}} i64 @"?f7@@YA?AUS7@@XZ"()
-// CHECK: call i64 {{.*}}func7{{.*}}(i64 {{.*}})
+// CHECK: define {{.*}} i8 @"?f7@@YA?AUS7@@XZ"()
+// CHECK: call i8 {{.*}}func7{{.*}}(i64 {{.*}})
 struct S7 {
   S6a x;
 };
Index: clang/test/CodeGen/arm64-arguments.c
===
--- clang/test/CodeGen/arm64-arguments.c
+++ clang/test/CodeGen/arm64-arguments.c
@@ -5,29 +5,28 @@
   return 0;
 }
 
-// Struct as return type. Aggregates <= 16 bytes are passed directly and round
-// up to multiple of 8 bytes.
-// CHECK: define{{.*}} i64 @f1()
+// Struct as return type. Aggregates <= 16 bytes are passed 

[PATCH] D100225: [Clang][AArch64] Coerce integer return values through an undef vector

2021-04-11 Thread Andrew Savonichev via Phabricator via cfe-commits
asavonic added a comment.

So we can just remove this rounding from `classifyReturnType`?
Thanks a lot John! I will upload this change as a separate review.


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D100225

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


[PATCH] D100225: [Clang][AArch64] Coerce integer return values through an undef vector

2021-04-11 Thread Andrew Savonichev via Phabricator via cfe-commits
asavonic added a comment.

In D100225#2681809 , @rjmccall wrote:

> Why does the ABI "require" this to be returned as an i64 if some of the bits 
> are undefined?

AArch64 ABI requires return values (of composite types) to be rounded up to 64 
bits (see `AArch64ABIInfo::classifyReturnType`). I assume that if a value, say 
i16, is rounded up to i64, then the upper 48 bits can be arbitrary (undefined). 
I think this is aligned with the description of `CreateCoercedLoad`:

  /// CreateCoercedLoad - Create a load from \arg SrcPtr interpreted as
  /// a pointer to an object of type \arg Ty, known to be aligned to
  /// \arg SrcAlign bytes.
  ///
  /// This safely handles the case when the src type is smaller than the
  /// destination type; in this situation the values of bits which not
  /// present in the src are undefined.


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D100225

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


[PATCH] D100225: [Clang][AArch64] Coerce integer return values through an undef vector

2021-04-09 Thread Andrew Savonichev via Phabricator via cfe-commits
asavonic created this revision.
Herald added subscribers: danielkiss, kristof.beyls.
asavonic requested review of this revision.
Herald added a project: clang.
Herald added a subscriber: cfe-commits.

If target ABI requires coercion to a larger type, higher bits of the
resulting value are supposed to be undefined. However, before this
patch Clang CG used to generate a `zext` instruction to coerce a value
to a larger type, forcing higher bits to zero.

This is problematic in some cases:

  struct st {
int i;
  };
  struct st foo(i);
  struct st bar(int x) {
return foo(x);
  }

For AArch64 Clang generates the following LLVM IR:

  define i64 @bar(i32 %x) {
%call = call i64 @foo(i32 %0)
%coerce.val.ii = trunc i64 %call to i32
;; ... store to alloca and load back
%coerce.val.ii2 = zext i32 %1 to i64
ret i64 %coerce.val.ii2
  }

Coercion is done with a `trunc` and a `zext`. After optimizations we
get the following:

  define i64 @bar(i32 %x) local_unnamed_addr #0 {
  entry:
%call = tail call i64 @foo(i32 %x)
%coerce.val.ii2 = and i64 %call, 4294967295
ret i64 %coerce.val.ii2
  }

The compiler has to keep semantic of the `zext` instruction, even
though no extension or truncation is required in this case.
This extra `and` instruction also prevents tail call optimization.

In order to keep information about undefined higher bits, the patch
replaces `zext` with a sequence of an `insertelement` and a `bitcast`:

  define i64 @_Z3bari(i32 %x) local_unnamed_addr #0 {
  entry:
%call = tail call i64 @_Z3fooi(i32 %x) #2
%coerce.val.ii = trunc i64 %call to i32
%coerce.val.vec = insertelement <2 x i32> undef, i32 %coerce.val.ii, i8 0
%coerce.val.vec.ii = bitcast <2 x i32> %coerce.val.vec to i64
ret i64 %coerce.val.vec.ii
  }

InstCombiner can then fold this sequence into a nop, and allow tail
call optimization.


Repository:
  rG LLVM Github Monorepo

https://reviews.llvm.org/D100225

Files:
  clang/lib/CodeGen/CGCall.cpp
  clang/test/CodeGen/arm64-arguments.c
  clang/test/CodeGenCXX/trivial_abi.cpp

Index: clang/test/CodeGenCXX/trivial_abi.cpp
===
--- clang/test/CodeGenCXX/trivial_abi.cpp
+++ clang/test/CodeGenCXX/trivial_abi.cpp
@@ -202,7 +202,8 @@
 // CHECK: %[[RETVAL:.*]] = alloca %[[STRUCT_TRIVIAL:.*]], align 4
 // CHECK: %[[COERCE_DIVE:.*]] = getelementptr inbounds %[[STRUCT_TRIVIAL]], %[[STRUCT_TRIVIAL]]* %[[RETVAL]], i32 0, i32 0
 // CHECK: %[[V0:.*]] = load i32, i32* %[[COERCE_DIVE]], align 4
-// CHECK: %[[COERCE_VAL_II:.*]] = zext i32 %[[V0]] to i64
+// CHECK: %[[COERCE_VAL_VEC:.*]] = insertelement <2 x i32> undef, i32 %[[V0]], i8 0
+// CHECK: %[[COERCE_VAL_II:.*]] = bitcast <2 x i32> %[[COERCE_VAL_VEC]] to i64
 // CHECK: ret i64 %[[COERCE_VAL_II]]
 // CHECK: }
 
Index: clang/test/CodeGen/arm64-arguments.c
===
--- clang/test/CodeGen/arm64-arguments.c
+++ clang/test/CodeGen/arm64-arguments.c
@@ -745,3 +745,63 @@
 // CHECK: call <3 x float> (i32, ...) @test_hva_v3(i32 1, [4 x <4 x float>] {{.*}})
   return test_hva_v3(1, *a);
 }
+
+char ret_coerce1(void) {
+  // CHECK-LABEL: i8 @ret_coerce1
+  // CHECK:  alloca i8
+  // CHECK-NEXT: load i8
+  // CHECK-NEXT: ret i8
+}
+
+short ret_coerce2(void) {
+  // CHECK-LABEL: i16 @ret_coerce2
+  // CHECK:  alloca i16
+  // CHECK-NEXT: load i16
+  // CHECK-NEXT: ret i16
+}
+
+int ret_coerce3(void) {
+  // CHECK-LABEL: i32 @ret_coerce3
+  // CHECK:  alloca i32
+  // CHECK-NEXT: load i32
+  // CHECK-NEXT: ret i32
+}
+
+struct ret_coerce_char {
+  char f0;
+};
+struct ret_coerce_char ret_coerce4(void) {
+  // CHECK-LABEL: i64 @ret_coerce4
+  // CHECK: %[[ALLOCA:.*]] = alloca %struct.ret_coerce_char
+  // CHECK: %[[GEP:.*]] = getelementptr {{.*}} %[[ALLOCA]], i32 0, i32 0
+  // CHECK: %[[LOAD:.*]] = load i8, i8* %[[GEP]]
+  // CHECK: %[[VEC:.*]] = insertelement <8 x i8> undef, i8 %[[LOAD]], i8 0
+  // CHECK: %[[CAST:.*]] = bitcast <8 x i8> %[[VEC]] to i64
+  // CHECK: ret i64 %[[CAST]]
+}
+
+struct ret_coerce_short {
+  short f0;
+};
+struct ret_coerce_short ret_coerce5(void) {
+  // CHECK-LABEL: i64 @ret_coerce5
+  // CHECK: %[[ALLOCA:.*]] = alloca %struct.ret_coerce_short
+  // CHECK: %[[GEP:.*]] = getelementptr {{.*}} %[[ALLOCA]], i32 0, i32 0
+  // CHECK: %[[LOAD:.*]] = load i16, i16* %[[GEP]]
+  // CHECK: %[[VEC:.*]] = insertelement <4 x i16> undef, i16 %[[LOAD]], i8 0
+  // CHECK: %[[CAST:.*]] = bitcast <4 x i16> %[[VEC]] to i64
+  // CHECK: ret i64 %[[CAST]]
+}
+
+struct ret_coerce_int {
+  int f0;
+};
+struct ret_coerce_int ret_coerce6(void) {
+  // CHECK-LABEL: i64 @ret_coerce6
+  // CHECK: %[[ALLOCA:.*]] = alloca %struct.ret_coerce_int
+  // CHECK: %[[GEP:.*]] = getelementptr {{.*}} %[[ALLOCA]], i32 0, i32 0
+  // CHECK: %[[LOAD:.*]] = load i32, i32* %[[GEP]]
+  // CHECK: %[[VEC:.*]] = insertelement <2 x i32> undef, i32 %[[LOAD]], i8 0
+  // CHECK: %[[CAST:.*]] = bitcast <2 

[PATCH] D98895: [X86][Draft] Disable long double type for -mno-x87 option

2021-03-18 Thread Andrew Savonichev via Phabricator via cfe-commits
asavonic added a comment.

I'm not sure that this is the right approach, but I wanted to get feedback on
how the issue should be fixed. Currently, the compiler crashes on almost any
code with `long double` (excluding cases where CG does not properly disable 
x87):

  long double foo(long double x, long double y)
  {
long double z = x + y;
if (z < 0.0)
  return z;
else
  return 0.0;
  }


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D98895

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


[PATCH] D98895: [X86][Draft] Disable long double type for -mno-x87 option

2021-03-18 Thread Andrew Savonichev via Phabricator via cfe-commits
asavonic created this revision.
asavonic added a reviewer: andrew.w.kaylor.
Herald added a subscriber: pengfei.
asavonic requested review of this revision.
Herald added a project: clang.
Herald added a subscriber: cfe-commits.

This patch attempts to fix a compiler crash that occurs when `long double` type
is used with `-mno-x87` compiler option.

The option disables x87 target feature, which in turn disables x87 registers, so
CG cannot select them for `x86_fp80` LLVM IR type. Long double is lowered as
`x86_fp80` for some targets, so it leads to a crash.

The option seems to contradict the SystemV ABI, which requires `long double` to
be represented as a 80-bit floating point, and it also requires to use x87 
registers.


Repository:
  rG LLVM Github Monorepo

https://reviews.llvm.org/D98895

Files:
  clang/include/clang/Basic/TargetInfo.h
  clang/lib/Basic/TargetInfo.cpp
  clang/lib/Basic/Targets/X86.cpp
  clang/lib/Basic/Targets/X86.h
  clang/lib/Sema/SemaChecking.cpp
  clang/lib/Sema/SemaDecl.cpp
  clang/lib/Sema/SemaExpr.cpp
  clang/test/Sema/x86-no-x87.c

Index: clang/test/Sema/x86-no-x87.c
===
--- /dev/null
+++ clang/test/Sema/x86-no-x87.c
@@ -0,0 +1,61 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s -triple x86_64-linux-gnu -target-feature -x87
+// RUN: %clang_cc1 -fsyntax-only -verify %s -triple x86_64-linux-gnu -DNOERROR
+
+#ifdef NOERROR
+// expected-no-diagnostics
+#endif
+
+typedef long double long_double;
+
+#ifndef NOERROR
+// expected-error@+3{{long double is not supported on this target}}
+// expected-error@+2{{long double is not supported on this target}}
+#endif
+double ld_args(long_double x, long_double y);
+
+long_double ld_ret(double x, double y);
+
+double args(double x, double y) {
+  return ld_args(x, y);
+}
+
+double ret(double x, double y) {
+#ifndef NOERROR
+  // expected-error@+2{{long double is not supported on this target}}
+#endif
+  return ld_ret(x, y);
+}
+
+double binop(double x, double y) {
+#ifndef NOERROR
+  // expected-error@+2{{long double is not supported on this target}}
+#endif
+  double z = (long_double)x * (long_double)y;
+  return z;
+}
+
+void assign1(long_double *ret, double x) {
+#ifndef NOERROR
+  // expected-error@+2{{long double is not supported on this target}}
+#endif
+  *ret = x;
+}
+
+struct st_long_double {
+  long_double ld;
+};
+
+void assign2() {
+  struct st_long_double st;
+#ifndef NOERROR
+  // expected-error@+2{{long double is not supported on this target}}
+#endif
+  st.ld = 0.42;
+}
+
+void assign3() {
+#ifndef NOERROR
+  // expected-error@+2{{long double is not supported on this target}}
+#endif
+  long_double ld = 0.42;
+}
Index: clang/lib/Sema/SemaExpr.cpp
===
--- clang/lib/Sema/SemaExpr.cpp
+++ clang/lib/Sema/SemaExpr.cpp
@@ -13917,6 +13917,17 @@
 }
   }
 
+  if (!Context.getTargetInfo().hasLongDoubleType()) {
+QualType LHSTy = LHSExpr->getType();
+QualType RHSTy = RHSExpr->getType();
+
+if ((LHSTy.getCanonicalType() == Context.LongDoubleTy) ||
+(RHSTy.getCanonicalType() == Context.LongDoubleTy)) {
+  Diag(OpLoc, diag::err_type_unsupported) << "long double";
+  return ExprError();
+}
+  }
+
   switch (Opc) {
   case BO_Assign:
 ResultTy = CheckAssignmentOperands(LHS.get(), RHS, OpLoc, QualType());
@@ -14755,6 +14766,13 @@
   if (Opc != UO_AddrOf && Opc != UO_Deref)
 CheckArrayAccess(Input.get());
 
+  if (!Context.getTargetInfo().hasLongDoubleType() &&
+  (resultType.getCanonicalType() == Context.LongDoubleTy ||
+   InputExpr->getType().getCanonicalType() == Context.LongDoubleTy)) {
+Diag(OpLoc, diag::err_type_unsupported) << "long double";
+return ExprError();
+  }
+
   auto *UO =
   UnaryOperator::Create(Context, Input.get(), Opc, resultType, VK, OK,
 OpLoc, CanOverflow, CurFPFeatureOverrides());
Index: clang/lib/Sema/SemaDecl.cpp
===
--- clang/lib/Sema/SemaDecl.cpp
+++ clang/lib/Sema/SemaDecl.cpp
@@ -7244,6 +7244,11 @@
 diagnoseOpenCLTypes(S, *this, D, DC, NewVD->getType());
   }
 
+  if (!Context.getTargetInfo().hasLongDoubleType() &&
+  NewVD->getType().getCanonicalType() == Context.LongDoubleTy) {
+Diag(NewVD->getLocation(), diag::err_type_unsupported) << "long double";
+  }
+
   // Handle attributes prior to checking for duplicates in MergeVarDecl
   ProcessDeclAttributes(S, NewVD, D);
 
@@ -14136,6 +14141,17 @@
   CheckParmsForFunctionDef(FD->parameters(),
/*CheckParameterNames=*/true);
 
+  if (!Context.getTargetInfo().hasLongDoubleType()) {
+if (ResultType.getCanonicalType() == Context.LongDoubleTy) {
+  Diag(FD->getLocation(), diag::err_type_unsupported) << "long double";
+}
+for (ParmVarDecl *Param : FD->parameters()) {
+  if (Param->getType().getCanonicalType() == Context.LongDoubleTy) {

[PATCH] D89909: [SYCL] Implement SYCL address space attributes handling

2020-11-13 Thread Andrew Savonichev via Phabricator via cfe-commits
asavonic added inline comments.



Comment at: clang/lib/CodeGen/CGExpr.cpp:4554
+
+  // Language rules define if it is legal to cast from one address space
+  // to another, and which address space we should use as a "common

bader wrote:
> asavonic wrote:
> > sdmitriev wrote:
> > > bader wrote:
> > > > Anastasia wrote:
> > > > > What language rules?
> > > > I suppose it's a generic note and author didn't meant some particular 
> > > > language here. This change was contributed by @sdmitriev. 
> > > > @sdmitriev, could you clarify, please?
> > > This comment was originally added by @asavonic to 
> > > clang/lib/CodeGen/CGExprScalar.cpp (lines 2962-2965 in this patch), and 
> > > later I reused his code along with the comment in this file while fixing 
> > > a very similar issue. So, I guess it would be more correct to ask Andrew 
> > > to clarify. @asavonic, can you please comment on this?
> > > This comment was originally added by @asavonic to 
> > > clang/lib/CodeGen/CGExprScalar.cpp (lines 2962-2965 in this patch), and 
> > > later I reused his code along with the comment in this file while fixing 
> > > a very similar issue.
> > 
> > There is `if (Opts.SYCLIsDevice)` In CGExprScalar.cpp, so we handle SYCL 
> > language rules.
> > In SYCL, (almost) all pointers have default address space in AST, but in CG 
> > some pointers become private/local/global, and some are lowered as generic 
> > pointers. We need to add an implicit addrspacecast in CG to emit an 
> > expression that expects the same type for its operands.
> > 
> > For example:
> > const char *str = ... ;
> > const char *phi_str = i > 2 ? str : "hello world!";
> > 
> > In AST types of `str` and `"hello world"` are the same (`const char *`). In 
> > CG we emit `str` as `i8 addrspace(4)*` and `"hello world"` as `i8*`. At 
> > this point we have to decide what type `phi_str` should have, and 
> > addrspacecast the operands accordingly.
> Is it possible to avoid fixing address space mismatch at this point by 
> adjusting AST as suggested by John in this comment: 
> https://reviews.llvm.org/D89909#inline-837495?
> 
> I wonder if it can be done w/o impacting C++ template metaprogramming as 
> noted in this thread: 
> http://clang-developers.42468.n3.nabble.com/RFC-Re-use-OpenCL-address-space-attributes-for-SYCL-td4068754.html.
> Is it possible to avoid fixing address space mismatch at this point by 
> adjusting AST

Some address space mismatches are present in CG already, see 
CodeGenModule::getStringLiteralAddressSpace and 
CodeGenModule::GetGlobalVarAddressSpace. This should be moved to AST (or 
replaced) as well, right?


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D89909

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


[PATCH] D89909: [SYCL] Implement SYCL address space attributes handling

2020-11-13 Thread Andrew Savonichev via Phabricator via cfe-commits
asavonic added inline comments.



Comment at: clang/lib/CodeGen/CGExpr.cpp:4554
+
+  // Language rules define if it is legal to cast from one address space
+  // to another, and which address space we should use as a "common

sdmitriev wrote:
> bader wrote:
> > Anastasia wrote:
> > > What language rules?
> > I suppose it's a generic note and author didn't meant some particular 
> > language here. This change was contributed by @sdmitriev. 
> > @sdmitriev, could you clarify, please?
> This comment was originally added by @asavonic to 
> clang/lib/CodeGen/CGExprScalar.cpp (lines 2962-2965 in this patch), and later 
> I reused his code along with the comment in this file while fixing a very 
> similar issue. So, I guess it would be more correct to ask Andrew to clarify. 
> @asavonic, can you please comment on this?
> This comment was originally added by @asavonic to 
> clang/lib/CodeGen/CGExprScalar.cpp (lines 2962-2965 in this patch), and later 
> I reused his code along with the comment in this file while fixing a very 
> similar issue.

There is `if (Opts.SYCLIsDevice)` In CGExprScalar.cpp, so we handle SYCL 
language rules.
In SYCL, (almost) all pointers have default address space in AST, but in CG 
some pointers become private/local/global, and some are lowered as generic 
pointers. We need to add an implicit addrspacecast in CG to emit an expression 
that expects the same type for its operands.

For example:
const char *str = ... ;
const char *phi_str = i > 2 ? str : "hello world!";

In AST types of `str` and `"hello world"` are the same (`const char *`). In CG 
we emit `str` as `i8 addrspace(4)*` and `"hello world"` as `i8*`. At this point 
we have to decide what type `phi_str` should have, and addrspacecast the 
operands accordingly.


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D89909

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


[PATCH] D71460: [OpenCL] Fix support for cl_khr_mipmap_image_writes

2019-12-13 Thread Andrew Savonichev via Phabricator via cfe-commits
asavonic added a comment.

What about `get_image_num_mip_levels` functions defined in the extension 
specification?




Comment at: clang/lib/Headers/opencl-c.h:14780
 
 void __ovld write_imagef(read_write image2d_depth_t image, int2 coord, int 
lod, float color);
 void __ovld write_imagef(read_write image2d_array_depth_t image, int4 coord, 
int lod, float color);

Shouldn't "color" be renamed to "depth" here as well?


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D71460



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


[PATCH] D63256: [OpenCL] Split type and macro definitions into opencl-c-base.h

2019-06-18 Thread Andrew Savonichev via Phabricator via cfe-commits
asavonic accepted this revision.
asavonic added a comment.
This revision is now accepted and ready to land.

Thanks. LGTM.


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

https://reviews.llvm.org/D63256



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


[PATCH] D63256: [OpenCL] Split type and macro definitions into opencl-c-base.h

2019-06-14 Thread Andrew Savonichev via Phabricator via cfe-commits
asavonic added a comment.

LGTM, except for the `IncludeDefaultHeader` and `DeclareOpenCLBuiltins` logic.




Comment at: lib/Frontend/CompilerInvocation.cpp:2194
 }
+// Include base header file for builtin types and constants.
+if (Opts.DeclareOpenCLBuiltins) {

Can we have the following logic instead? Otherwise `DeclareOpenCLBuiltins` 
implies `IncludeDefaultHeader` which is not always the case.

```
if (Opts.IncludeDefaultHeader) {
  if (Opts.DeclareOpenCLBuiltins) {
PPOpts.Includes.push_back("opencl-c-base.h");
  } else {
PPOpts.Includes.push_back("opencl-c.h");
  }
}
```


Repository:
  rC Clang

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

https://reviews.llvm.org/D63256



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


[PATCH] D58666: [OpenCL] Undefine cl_intel_planar_yuv extension

2019-06-03 Thread Andrew Savonichev via Phabricator via cfe-commits
This revision was automatically updated to reflect the committed changes.
Closed by commit rL362398: [OpenCL] Undefine cl_intel_planar_yuv extension 
(authored by asavonic, committed by ).
Herald added a project: LLVM.
Herald added a subscriber: llvm-commits.

Changed prior to commit:
  https://reviews.llvm.org/D58666?vs=188338=202700#toc

Repository:
  rL LLVM

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

https://reviews.llvm.org/D58666

Files:
  cfe/trunk/lib/Headers/opencl-c.h
  cfe/trunk/test/Headers/opencl-c-header.cl
  cfe/trunk/test/SemaOpenCL/extension-begin.cl


Index: cfe/trunk/test/Headers/opencl-c-header.cl
===
--- cfe/trunk/test/Headers/opencl-c-header.cl
+++ cfe/trunk/test/Headers/opencl-c-header.cl
@@ -77,9 +77,6 @@
 // OpenCL 1.2 onwards.
 #if defined(__OPENCL_CPP_VERSION__) || (__OPENCL_C_VERSION__ >= CL_VERSION_1_2)
 // expected-no-diagnostics
-#ifndef cl_intel_planar_yuv
-#error "Missing cl_intel_planar_yuv define"
-#endif
 #else //__OPENCL_C_VERSION__
 // expected-warning@+2{{unknown OpenCL extension 'cl_intel_planar_yuv' - 
ignoring}}
 #endif //__OPENCL_C_VERSION__
Index: cfe/trunk/test/SemaOpenCL/extension-begin.cl
===
--- cfe/trunk/test/SemaOpenCL/extension-begin.cl
+++ cfe/trunk/test/SemaOpenCL/extension-begin.cl
@@ -16,6 +16,13 @@
 //
 // RUN: %clang_cc1 -cl-std=CL2.0 -DIMPLICIT_INCLUDE -include 
%S/extension-begin.h -triple spir-unknown-unknown -O0 -emit-llvm -o - -fmodules 
-fimplicit-module-maps -fmodules-cache-path=%t.modules %s -verify -pedantic
 
+#pragma OPENCL EXTENSION my_ext : enable
+#ifndef IMPLICIT_INCLUDE
+// expected-warning@-2 {{unknown OpenCL extension 'my_ext' - ignoring}}
+// expected-warning@+2 {{unknown OpenCL extension 'my_ext' - ignoring}}
+#endif // IMPLICIT_INCLUDE
+#pragma OPENCL EXTENSION my_ext : disable
+
 #ifndef IMPLICIT_INCLUDE
 #include "extension-begin.h"
 #endif // IMPLICIT_INCLUDE
Index: cfe/trunk/lib/Headers/opencl-c.h
===
--- cfe/trunk/lib/Headers/opencl-c.h
+++ cfe/trunk/lib/Headers/opencl-c.h
@@ -22,9 +22,6 @@
 #endif //__OPENCL_C_VERSION__ < CL_VERSION_2_0
 
 #if __OPENCL_C_VERSION__ >= CL_VERSION_1_2
-#ifndef cl_intel_planar_yuv
-#define cl_intel_planar_yuv
-#endif // cl_intel_planar_yuv
 #pragma OPENCL EXTENSION cl_intel_planar_yuv : begin
 #pragma OPENCL EXTENSION cl_intel_planar_yuv : end
 #endif // __OPENCL_C_VERSION__ >= CL_VERSION_1_2


Index: cfe/trunk/test/Headers/opencl-c-header.cl
===
--- cfe/trunk/test/Headers/opencl-c-header.cl
+++ cfe/trunk/test/Headers/opencl-c-header.cl
@@ -77,9 +77,6 @@
 // OpenCL 1.2 onwards.
 #if defined(__OPENCL_CPP_VERSION__) || (__OPENCL_C_VERSION__ >= CL_VERSION_1_2)
 // expected-no-diagnostics
-#ifndef cl_intel_planar_yuv
-#error "Missing cl_intel_planar_yuv define"
-#endif
 #else //__OPENCL_C_VERSION__
 // expected-warning@+2{{unknown OpenCL extension 'cl_intel_planar_yuv' - ignoring}}
 #endif //__OPENCL_C_VERSION__
Index: cfe/trunk/test/SemaOpenCL/extension-begin.cl
===
--- cfe/trunk/test/SemaOpenCL/extension-begin.cl
+++ cfe/trunk/test/SemaOpenCL/extension-begin.cl
@@ -16,6 +16,13 @@
 //
 // RUN: %clang_cc1 -cl-std=CL2.0 -DIMPLICIT_INCLUDE -include %S/extension-begin.h -triple spir-unknown-unknown -O0 -emit-llvm -o - -fmodules -fimplicit-module-maps -fmodules-cache-path=%t.modules %s -verify -pedantic
 
+#pragma OPENCL EXTENSION my_ext : enable
+#ifndef IMPLICIT_INCLUDE
+// expected-warning@-2 {{unknown OpenCL extension 'my_ext' - ignoring}}
+// expected-warning@+2 {{unknown OpenCL extension 'my_ext' - ignoring}}
+#endif // IMPLICIT_INCLUDE
+#pragma OPENCL EXTENSION my_ext : disable
+
 #ifndef IMPLICIT_INCLUDE
 #include "extension-begin.h"
 #endif // IMPLICIT_INCLUDE
Index: cfe/trunk/lib/Headers/opencl-c.h
===
--- cfe/trunk/lib/Headers/opencl-c.h
+++ cfe/trunk/lib/Headers/opencl-c.h
@@ -22,9 +22,6 @@
 #endif //__OPENCL_C_VERSION__ < CL_VERSION_2_0
 
 #if __OPENCL_C_VERSION__ >= CL_VERSION_1_2
-#ifndef cl_intel_planar_yuv
-#define cl_intel_planar_yuv
-#endif // cl_intel_planar_yuv
 #pragma OPENCL EXTENSION cl_intel_planar_yuv : begin
 #pragma OPENCL EXTENSION cl_intel_planar_yuv : end
 #endif // __OPENCL_C_VERSION__ >= CL_VERSION_1_2
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D59493: [OpenCL] Generate 'unroll.enable' metadata for __attribute__((opencl_unroll_hint))

2019-03-20 Thread Andrew Savonichev via Phabricator via cfe-commits
This revision was automatically updated to reflect the committed changes.
Closed by commit rC356571: [OpenCL] Generate unroll.enable metadata 
for  __attribute__… (authored by asavonic, committed by ).

Repository:
  rC Clang

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

https://reviews.llvm.org/D59493

Files:
  lib/CodeGen/CGLoopInfo.cpp
  test/CodeGenOpenCL/unroll-hint.cl


Index: lib/CodeGen/CGLoopInfo.cpp
===
--- lib/CodeGen/CGLoopInfo.cpp
+++ lib/CodeGen/CGLoopInfo.cpp
@@ -208,13 +208,13 @@
 // Translate opencl_unroll_hint attribute argument to
 // equivalent LoopHintAttr enums.
 // OpenCL v2.0 s6.11.5:
-// 0 - full unroll (no argument).
+// 0 - enable unroll (no argument).
 // 1 - disable unroll.
 // other positive integer n - unroll by n.
 if (OpenCLHint) {
   ValueInt = OpenCLHint->getUnrollHint();
   if (ValueInt == 0) {
-State = LoopHintAttr::Full;
+State = LoopHintAttr::Enable;
   } else if (ValueInt != 1) {
 Option = LoopHintAttr::UnrollCount;
 State = LoopHintAttr::Numeric;
Index: test/CodeGenOpenCL/unroll-hint.cl
===
--- test/CodeGenOpenCL/unroll-hint.cl
+++ test/CodeGenOpenCL/unroll-hint.cl
@@ -18,12 +18,12 @@
 // CHECK: br label %{{.*}}, !llvm.loop ![[FOR_DISABLE:.*]]
 }
 
-void for_full()
+void for_enable()
 {
-// CHECK-LABEL: for_full
+// CHECK-LABEL: for_enable
 __attribute__((opencl_unroll_hint))
 for( int i = 0; i < 1000; ++i);
-// CHECK: br label %{{.*}}, !llvm.loop ![[FOR_FULL:.*]]
+// CHECK: br label %{{.*}}, !llvm.loop ![[FOR_ENABLE:.*]]
 }
 
 /*** while ***/
@@ -45,13 +45,13 @@
 // CHECK: br label %{{.*}}, !llvm.loop ![[WHILE_DISABLE:.*]]
 }
 
-void while_full()
+void while_enable()
 {
-// CHECK-LABEL: while_full
+// CHECK-LABEL: while_enable
 int i = 1000;
 __attribute__((opencl_unroll_hint))
 while(i-->0);
-// CHECK: br label %{{.*}}, !llvm.loop ![[WHILE_FULL:.*]]
+// CHECK: br label %{{.*}}, !llvm.loop ![[WHILE_ENABLE:.*]]
 }
 
 /*** do ***/
@@ -73,13 +73,13 @@
 // CHECK: br i1 %{{.*}}, label %{{.*}}, label %{{.*}}, !llvm.loop 
![[DO_DISABLE:.*]]
 }
 
-void do_full()
+void do_enable()
 {
-// CHECK-LABEL: do_full
+// CHECK-LABEL: do_enable
 int i = 1000;
 __attribute__((opencl_unroll_hint))
 do {} while(i--> 0);
-// CHECK: br i1 %{{.*}}, label %{{.*}}, label %{{.*}}, !llvm.loop 
![[DO_FULL:.*]]
+// CHECK: br i1 %{{.*}}, label %{{.*}}, label %{{.*}}, !llvm.loop 
![[DO_ENABLE:.*]]
 }
 
 
@@ -87,11 +87,11 @@
 // CHECK: ![[COUNT]] =  !{!"llvm.loop.unroll.count", i32 8}
 // CHECK: ![[FOR_DISABLE]]   =  distinct !{![[FOR_DISABLE]],  ![[DISABLE:.*]]}
 // CHECK: ![[DISABLE]]   =  !{!"llvm.loop.unroll.disable"}
-// CHECK: ![[FOR_FULL]]  =  distinct !{![[FOR_FULL]],  ![[FULL:.*]]}
-// CHECK: ![[FULL]]  =  !{!"llvm.loop.unroll.full"}
+// CHECK: ![[FOR_ENABLE]]  =  distinct !{![[FOR_ENABLE]],  ![[ENABLE:.*]]}
+// CHECK: ![[ENABLE]]  =  !{!"llvm.loop.unroll.enable"}
 // CHECK: ![[WHILE_COUNT]]   =  distinct !{![[WHILE_COUNT]],![[COUNT]]}
 // CHECK: ![[WHILE_DISABLE]] =  distinct !{![[WHILE_DISABLE]],  ![[DISABLE]]}
-// CHECK: ![[WHILE_FULL]]=  distinct !{![[WHILE_FULL]], ![[FULL]]}
+// CHECK: ![[WHILE_ENABLE]]=  distinct !{![[WHILE_ENABLE]], 
![[ENABLE]]}
 // CHECK: ![[DO_COUNT]]  =  distinct !{![[DO_COUNT]],   ![[COUNT]]}
 // CHECK: ![[DO_DISABLE]]=  distinct !{![[DO_DISABLE]], ![[DISABLE]]}
-// CHECK: ![[DO_FULL]]   =  distinct !{![[DO_FULL]],![[FULL]]}
+// CHECK: ![[DO_ENABLE]]   =  distinct !{![[DO_ENABLE]],
![[ENABLE]]}


Index: lib/CodeGen/CGLoopInfo.cpp
===
--- lib/CodeGen/CGLoopInfo.cpp
+++ lib/CodeGen/CGLoopInfo.cpp
@@ -208,13 +208,13 @@
 // Translate opencl_unroll_hint attribute argument to
 // equivalent LoopHintAttr enums.
 // OpenCL v2.0 s6.11.5:
-// 0 - full unroll (no argument).
+// 0 - enable unroll (no argument).
 // 1 - disable unroll.
 // other positive integer n - unroll by n.
 if (OpenCLHint) {
   ValueInt = OpenCLHint->getUnrollHint();
   if (ValueInt == 0) {
-State = LoopHintAttr::Full;
+State = LoopHintAttr::Enable;
   } else if (ValueInt != 1) {
 Option = LoopHintAttr::UnrollCount;
 State = LoopHintAttr::Numeric;
Index: test/CodeGenOpenCL/unroll-hint.cl
===
--- test/CodeGenOpenCL/unroll-hint.cl
+++ test/CodeGenOpenCL/unroll-hint.cl
@@ -18,12 +18,12 @@
 // CHECK: br label %{{.*}}, !llvm.loop ![[FOR_DISABLE:.*]]
 }
 
-void for_full()
+void for_enable()
 {
-// CHECK-LABEL: for_full
+// CHECK-LABEL: for_enable
 __attribute__((opencl_unroll_hint))
 for( int i = 0; i < 1000; ++i);
-// CHECK: br label %{{.*}}, 

[PATCH] D58388: [OpenCL] Simplify LLVM IR generated for OpenCL blocks

2019-02-21 Thread Andrew Savonichev via Phabricator via cfe-commits
This revision was automatically updated to reflect the committed changes.
Closed by commit rC354568: [OpenCL] Simplify LLVM IR generated for OpenCL 
blocks (authored by asavonic, committed by ).

Repository:
  rC Clang

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

https://reviews.llvm.org/D58388

Files:
  lib/CodeGen/CGBlocks.cpp
  lib/CodeGen/CGOpenCLRuntime.cpp
  lib/CodeGen/CGOpenCLRuntime.h
  test/CodeGenOpenCL/blocks.cl
  test/CodeGenOpenCL/cl20-device-side-enqueue.cl

Index: lib/CodeGen/CGOpenCLRuntime.h
===
--- lib/CodeGen/CGOpenCLRuntime.h
+++ lib/CodeGen/CGOpenCLRuntime.h
@@ -91,6 +91,10 @@
   /// \param Block block literal emitted for the block expression.
   void recordBlockInfo(const BlockExpr *E, llvm::Function *InvokeF,
llvm::Value *Block);
+
+  /// \return LLVM block invoke function emitted for an expression derived from
+  /// the block expression.
+  llvm::Function *getInvokeFunction(const Expr *E);
 };
 
 }
Index: lib/CodeGen/CGBlocks.cpp
===
--- lib/CodeGen/CGBlocks.cpp
+++ lib/CodeGen/CGBlocks.cpp
@@ -1253,52 +1253,49 @@
   ReturnValueSlot ReturnValue) {
   const BlockPointerType *BPT =
 E->getCallee()->getType()->getAs();
-
   llvm::Value *BlockPtr = EmitScalarExpr(E->getCallee());
-
-  // Get a pointer to the generic block literal.
-  // For OpenCL we generate generic AS void ptr to be able to reuse the same
-  // block definition for blocks with captures generated as private AS local
-  // variables and without captures generated as global AS program scope
-  // variables.
-  unsigned AddrSpace = 0;
-  if (getLangOpts().OpenCL)
-AddrSpace = getContext().getTargetAddressSpace(LangAS::opencl_generic);
-
-  llvm::Type *BlockLiteralTy =
-  llvm::PointerType::get(CGM.getGenericBlockLiteralType(), AddrSpace);
-
-  // Bitcast the callee to a block literal.
-  BlockPtr =
-  Builder.CreatePointerCast(BlockPtr, BlockLiteralTy, "block.literal");
-
-  // Get the function pointer from the literal.
-  llvm::Value *FuncPtr =
-  Builder.CreateStructGEP(CGM.getGenericBlockLiteralType(), BlockPtr,
-  CGM.getLangOpts().OpenCL ? 2 : 3);
-
-  // Add the block literal.
+  llvm::Type *GenBlockTy = CGM.getGenericBlockLiteralType();
+  llvm::Value *Func = nullptr;
+  QualType FnType = BPT->getPointeeType();
+  ASTContext  = getContext();
   CallArgList Args;
 
-  QualType VoidPtrQualTy = getContext().VoidPtrTy;
-  llvm::Type *GenericVoidPtrTy = VoidPtrTy;
   if (getLangOpts().OpenCL) {
-GenericVoidPtrTy = CGM.getOpenCLRuntime().getGenericVoidPointerType();
-VoidPtrQualTy =
-getContext().getPointerType(getContext().getAddrSpaceQualType(
-getContext().VoidTy, LangAS::opencl_generic));
-  }
-
-  BlockPtr = Builder.CreatePointerCast(BlockPtr, GenericVoidPtrTy);
-  Args.add(RValue::get(BlockPtr), VoidPtrQualTy);
-
-  QualType FnType = BPT->getPointeeType();
+// For OpenCL, BlockPtr is already casted to generic block literal.
 
-  // And the rest of the arguments.
-  EmitCallArgs(Args, FnType->getAs(), E->arguments());
+// First argument of a block call is a generic block literal casted to
+// generic void pointer, i.e. i8 addrspace(4)*
+llvm::Value *BlockDescriptor = Builder.CreatePointerCast(
+BlockPtr, CGM.getOpenCLRuntime().getGenericVoidPointerType());
+QualType VoidPtrQualTy = Ctx.getPointerType(
+Ctx.getAddrSpaceQualType(Ctx.VoidTy, LangAS::opencl_generic));
+Args.add(RValue::get(BlockDescriptor), VoidPtrQualTy);
+// And the rest of the arguments.
+EmitCallArgs(Args, FnType->getAs(), E->arguments());
+
+// We *can* call the block directly unless it is a function argument.
+if (!isa(E->getCalleeDecl()))
+  Func = CGM.getOpenCLRuntime().getInvokeFunction(E->getCallee());
+else {
+  llvm::Value *FuncPtr = Builder.CreateStructGEP(GenBlockTy, BlockPtr, 2);
+  Func = Builder.CreateAlignedLoad(FuncPtr, getPointerAlign());
+}
+  } else {
+// Bitcast the block literal to a generic block literal.
+BlockPtr = Builder.CreatePointerCast(
+BlockPtr, llvm::PointerType::get(GenBlockTy, 0), "block.literal");
+// Get pointer to the block invoke function
+llvm::Value *FuncPtr = Builder.CreateStructGEP(GenBlockTy, BlockPtr, 3);
+
+// First argument is a block literal casted to a void pointer
+BlockPtr = Builder.CreatePointerCast(BlockPtr, VoidPtrTy);
+Args.add(RValue::get(BlockPtr), Ctx.VoidPtrTy);
+// And the rest of the arguments.
+EmitCallArgs(Args, FnType->getAs(), E->arguments());
 
-  // Load the function.
-  llvm::Value *Func = Builder.CreateAlignedLoad(FuncPtr, getPointerAlign());
+// Load the function.
+Func = Builder.CreateAlignedLoad(FuncPtr, getPointerAlign());
+  }
 
   const FunctionType *FuncTy = 

[PATCH] D55262: [OpenCL] Fix for TBAA information of pointer after addresspacecast

2018-12-12 Thread Andrew Savonichev via Phabricator via cfe-commits
This revision was automatically updated to reflect the committed changes.
Closed by commit rL348919: [OpenCL] Fix for TBAA information of pointer after 
addresspacecast (authored by asavonic, committed by ).

Changed prior to commit:
  https://reviews.llvm.org/D55262?vs=177012=177827#toc

Repository:
  rL LLVM

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

https://reviews.llvm.org/D55262

Files:
  cfe/trunk/lib/CodeGen/CGExpr.cpp
  cfe/trunk/test/CodeGenOpenCLCXX/address-space-deduction2.cl


Index: cfe/trunk/lib/CodeGen/CGExpr.cpp
===
--- cfe/trunk/lib/CodeGen/CGExpr.cpp
+++ cfe/trunk/lib/CodeGen/CGExpr.cpp
@@ -4269,8 +4269,9 @@
 QualType DestTy = getContext().getPointerType(E->getType());
 llvm::Value *V = getTargetHooks().performAddrSpaceCast(
 *this, LV.getPointer(), E->getSubExpr()->getType().getAddressSpace(),
-DestTy.getAddressSpace(), ConvertType(DestTy));
-return MakeNaturalAlignPointeeAddrLValue(V, DestTy);
+E->getType().getAddressSpace(), ConvertType(DestTy));
+return MakeAddrLValue(Address(V, LV.getAddress().getAlignment()),
+  E->getType(), LV.getBaseInfo(), LV.getTBAAInfo());
   }
   case CK_ObjCObjectLValueCast: {
 LValue LV = EmitLValue(E->getSubExpr());
Index: cfe/trunk/test/CodeGenOpenCLCXX/address-space-deduction2.cl
===
--- cfe/trunk/test/CodeGenOpenCLCXX/address-space-deduction2.cl
+++ cfe/trunk/test/CodeGenOpenCLCXX/address-space-deduction2.cl
@@ -0,0 +1,20 @@
+// RUN: %clang_cc1 %s -triple spir-unknown-unknown -cl-std=c++ -O0 -emit-llvm 
-o - | FileCheck %s
+
+class P {
+public:
+  P(const P ) = default;
+
+  long A;
+  long B;
+};
+
+void foo(__global P *GPtr) {
+// CHECK: call void @llvm.memcpy{{.*}}, {{.*}}, i32 16
+  P Val = GPtr[0];
+}
+
+struct __attribute__((packed)) A { int X; };
+int test(__global A *GPtr) {
+// CHECK: {{.*}} = load i32, {{.*}}, align 1
+  return static_cast<__generic A &>(*GPtr).X;
+}


Index: cfe/trunk/lib/CodeGen/CGExpr.cpp
===
--- cfe/trunk/lib/CodeGen/CGExpr.cpp
+++ cfe/trunk/lib/CodeGen/CGExpr.cpp
@@ -4269,8 +4269,9 @@
 QualType DestTy = getContext().getPointerType(E->getType());
 llvm::Value *V = getTargetHooks().performAddrSpaceCast(
 *this, LV.getPointer(), E->getSubExpr()->getType().getAddressSpace(),
-DestTy.getAddressSpace(), ConvertType(DestTy));
-return MakeNaturalAlignPointeeAddrLValue(V, DestTy);
+E->getType().getAddressSpace(), ConvertType(DestTy));
+return MakeAddrLValue(Address(V, LV.getAddress().getAlignment()),
+  E->getType(), LV.getBaseInfo(), LV.getTBAAInfo());
   }
   case CK_ObjCObjectLValueCast: {
 LValue LV = EmitLValue(E->getSubExpr());
Index: cfe/trunk/test/CodeGenOpenCLCXX/address-space-deduction2.cl
===
--- cfe/trunk/test/CodeGenOpenCLCXX/address-space-deduction2.cl
+++ cfe/trunk/test/CodeGenOpenCLCXX/address-space-deduction2.cl
@@ -0,0 +1,20 @@
+// RUN: %clang_cc1 %s -triple spir-unknown-unknown -cl-std=c++ -O0 -emit-llvm -o - | FileCheck %s
+
+class P {
+public:
+  P(const P ) = default;
+
+  long A;
+  long B;
+};
+
+void foo(__global P *GPtr) {
+// CHECK: call void @llvm.memcpy{{.*}}, {{.*}}, i32 16
+  P Val = GPtr[0];
+}
+
+struct __attribute__((packed)) A { int X; };
+int test(__global A *GPtr) {
+// CHECK: {{.*}} = load i32, {{.*}}, align 1
+  return static_cast<__generic A &>(*GPtr).X;
+}
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D54947: [OpenCL][CodeGen] Fix replacing memcpy with addrspacecast

2018-12-10 Thread Andrew Savonichev via Phabricator via cfe-commits
This revision was automatically updated to reflect the committed changes.
Closed by commit rC348752: [OpenCL][CodeGen] Fix replacing memcpy with 
addrspacecast (authored by asavonic, committed by ).

Repository:
  rC Clang

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

https://reviews.llvm.org/D54947

Files:
  lib/CodeGen/CGCall.cpp
  test/CodeGenOpenCL/addr-space-struct-arg.cl


Index: test/CodeGenOpenCL/addr-space-struct-arg.cl
===
--- test/CodeGenOpenCL/addr-space-struct-arg.cl
+++ test/CodeGenOpenCL/addr-space-struct-arg.cl
@@ -1,6 +1,9 @@
-// RUN: %clang_cc1 %s -emit-llvm -o - -O0 -finclude-default-header 
-ffake-address-space-map -triple i686-pc-darwin | FileCheck -enable-var-scope 
-check-prefixes=COM,X86 %s
-// RUN: %clang_cc1 %s -emit-llvm -o - -O0 -finclude-default-header -triple 
amdgcn | FileCheck -enable-var-scope -check-prefixes=COM,AMDGCN %s
-// RUN: %clang_cc1 %s -emit-llvm -o - -cl-std=CL2.0 -O0 
-finclude-default-header -triple amdgcn | FileCheck -enable-var-scope 
-check-prefixes=COM,AMDGCN,AMDGCN20 %s
+// RUN: %clang_cc1 %s -emit-llvm -o - -O0 -ffake-address-space-map -triple 
i686-pc-darwin | FileCheck -enable-var-scope -check-prefixes=COM,X86 %s
+// RUN: %clang_cc1 %s -emit-llvm -o - -O0 -triple amdgcn | FileCheck 
-enable-var-scope -check-prefixes=COM,AMDGCN %s
+// RUN: %clang_cc1 %s -emit-llvm -o - -cl-std=CL2.0 -O0 -triple amdgcn | 
FileCheck -enable-var-scope -check-prefixes=COM,AMDGCN,AMDGCN20 %s
+// RUN: %clang_cc1 %s -emit-llvm -o - -cl-std=CL1.2 -O0 -triple 
spir-unknown-unknown-unknown | FileCheck -enable-var-scope -check-prefixes=SPIR 
%s
+
+typedef int int2 __attribute__((ext_vector_type(2)));
 
 typedef struct {
   int cells[9];
@@ -130,6 +133,12 @@
   FuncOneMember(u);
 }
 
+// SPIR: call void @llvm.memcpy.p0i8.p1i8.i32
+// SPIR-NOT: addrspacecast
+kernel void KernelOneMemberSpir(global struct StructOneMember* u) {
+  FuncOneMember(*u);
+}
+
 // AMDGCN-LABEL: define amdgpu_kernel void @KernelLargeOneMember(
 // AMDGCN:  %[[U:.*]] = alloca %struct.LargeStructOneMember, align 8, 
addrspace(5)
 // AMDGCN:  store %struct.LargeStructOneMember %u.coerce, 
%struct.LargeStructOneMember addrspace(5)* %[[U]], align 8
Index: lib/CodeGen/CGCall.cpp
===
--- lib/CodeGen/CGCall.cpp
+++ lib/CodeGen/CGCall.cpp
@@ -3958,15 +3958,28 @@
 } else if (I->hasLValue()) {
   auto LV = I->getKnownLValue();
   auto AS = LV.getAddressSpace();
+
   if ((!ArgInfo.getIndirectByVal() &&
(LV.getAlignment() >=
-getContext().getTypeAlignInChars(I->Ty))) ||
-  (ArgInfo.getIndirectByVal() &&
-   ((AS != LangAS::Default && AS != LangAS::opencl_private &&
- AS != CGM.getASTAllocaAddressSpace() {
+getContext().getTypeAlignInChars(I->Ty {
+NeedCopy = true;
+  }
+  if (!getLangOpts().OpenCL) {
+if ((ArgInfo.getIndirectByVal() &&
+(AS != LangAS::Default &&
+ AS != CGM.getASTAllocaAddressSpace( {
+  NeedCopy = true;
+}
+  }
+  // For OpenCL even if RV is located in default or alloca address 
space
+  // we don't want to perform address space cast for it.
+  else if ((ArgInfo.getIndirectByVal() &&
+Addr.getType()->getAddressSpace() != IRFuncTy->
+  getParamType(FirstIRArg)->getPointerAddressSpace())) {
 NeedCopy = true;
   }
 }
+
 if (NeedCopy) {
   // Create an aligned temporary, and copy to it.
   Address AI = CreateMemTempWithoutCast(


Index: test/CodeGenOpenCL/addr-space-struct-arg.cl
===
--- test/CodeGenOpenCL/addr-space-struct-arg.cl
+++ test/CodeGenOpenCL/addr-space-struct-arg.cl
@@ -1,6 +1,9 @@
-// RUN: %clang_cc1 %s -emit-llvm -o - -O0 -finclude-default-header -ffake-address-space-map -triple i686-pc-darwin | FileCheck -enable-var-scope -check-prefixes=COM,X86 %s
-// RUN: %clang_cc1 %s -emit-llvm -o - -O0 -finclude-default-header -triple amdgcn | FileCheck -enable-var-scope -check-prefixes=COM,AMDGCN %s
-// RUN: %clang_cc1 %s -emit-llvm -o - -cl-std=CL2.0 -O0 -finclude-default-header -triple amdgcn | FileCheck -enable-var-scope -check-prefixes=COM,AMDGCN,AMDGCN20 %s
+// RUN: %clang_cc1 %s -emit-llvm -o - -O0 -ffake-address-space-map -triple i686-pc-darwin | FileCheck -enable-var-scope -check-prefixes=COM,X86 %s
+// RUN: %clang_cc1 %s -emit-llvm -o - -O0 -triple amdgcn | FileCheck -enable-var-scope -check-prefixes=COM,AMDGCN %s
+// RUN: %clang_cc1 %s -emit-llvm -o - -cl-std=CL2.0 -O0 -triple amdgcn | FileCheck -enable-var-scope -check-prefixes=COM,AMDGCN,AMDGCN20 %s
+// RUN: %clang_cc1 %s -emit-llvm -o - -cl-std=CL1.2 -O0 -triple 

[PATCH] D54253: [OpenCL] Launch opencl-types.cl test only on x86

2018-11-26 Thread Andrew Savonichev via Phabricator via cfe-commits
asavonic added a comment.

>> FWIW, I'd vote for the first revision of this patch. From my
>> 
>>   understanding, the test verifies that libclang is able to parse OpenCL
>>   code correctly. It doesn't do anything specific to x86: target for x86 just
>>   happens to support a set of OpenCL extensions.
> 
> I am trying to understand what exactly does it bring into testing if the code 
> doesn't have anything target specific in there?

It brings the architecture that does not support any OpenCL extension,
thus we check that types are "invalid".

> Tests are not entirely free, so we can't test absolutely everything.

Right. There is no big difference b/w these two revisions, so I'll leave
that to your discretion.


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

https://reviews.llvm.org/D54253



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


[PATCH] D54253: [OpenCL] Launch opencl-types.cl test only on x86

2018-11-22 Thread Andrew Savonichev via Phabricator via cfe-commits
asavonic added a comment.

FWIW, I'd vote for the first revision of this patch. From my
understanding, the test verifies that libclang is able to parse OpenCL
code correctly. It doesn't do anything specific to x86: target for x86 just
happens to support a set of OpenCL extensions.


https://reviews.llvm.org/D54253



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


[PATCH] D51484: [OpenCL] Add support of cl_intel_device_side_avc_motion_estimation extension

2018-11-08 Thread Andrew Savonichev via Phabricator via cfe-commits
asavonic added a comment.

Committed in r346392.


Repository:
  rC Clang

https://reviews.llvm.org/D51484



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


[PATCH] D54253: [OpenCL][NFC] Improve test coverage of test/Index/opencl-types.cl

2018-11-08 Thread Andrew Savonichev via Phabricator via cfe-commits
asavonic added a comment.

LGTM.


Repository:
  rC Clang

https://reviews.llvm.org/D54253



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


[PATCH] D51484: [OpenCL] Add support of cl_intel_device_side_avc_motion_estimation extension

2018-11-07 Thread Andrew Savonichev via Phabricator via cfe-commits
asavonic added a comment.

I reverted this change in r346338, as it breaks Index/opencl-types.cl LIT test. 
See 
http://lab.llvm.org:8011/builders/clang-ppc64le-linux/builds/21503/steps/ninja%20check%201/logs/FAIL%3A%20Clang%3A%3Aopencl-types.cl


Repository:
  rL LLVM

https://reviews.llvm.org/D51484



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


[PATCH] D51484: [OpenCL] Add support of cl_intel_device_side_avc_motion_estimation extension

2018-11-07 Thread Andrew Savonichev via Phabricator via cfe-commits
This revision was automatically updated to reflect the committed changes.
Closed by commit rL346326: [OpenCL] Add support of 
cl_intel_device_side_avc_motion_estimation extension (authored by asavonic, 
committed by ).
Herald added a subscriber: llvm-commits.

Changed prior to commit:
  https://reviews.llvm.org/D51484?vs=172946=172956#toc

Repository:
  rL LLVM

https://reviews.llvm.org/D51484

Files:
  cfe/trunk/include/clang-c/Index.h
  cfe/trunk/include/clang/AST/ASTContext.h
  cfe/trunk/include/clang/AST/Type.h
  cfe/trunk/include/clang/Basic/OpenCLExtensionTypes.def
  cfe/trunk/include/clang/Basic/OpenCLExtensions.def
  cfe/trunk/include/clang/Sema/Initialization.h
  cfe/trunk/include/clang/Serialization/ASTBitCodes.h
  cfe/trunk/include/clang/module.modulemap
  cfe/trunk/lib/AST/ASTContext.cpp
  cfe/trunk/lib/AST/ASTImporter.cpp
  cfe/trunk/lib/AST/ExprConstant.cpp
  cfe/trunk/lib/AST/ItaniumMangle.cpp
  cfe/trunk/lib/AST/MicrosoftMangle.cpp
  cfe/trunk/lib/AST/NSAPI.cpp
  cfe/trunk/lib/AST/PrintfFormatString.cpp
  cfe/trunk/lib/AST/Type.cpp
  cfe/trunk/lib/AST/TypeLoc.cpp
  cfe/trunk/lib/CodeGen/CGDebugInfo.cpp
  cfe/trunk/lib/CodeGen/CGDebugInfo.h
  cfe/trunk/lib/CodeGen/CGExprScalar.cpp
  cfe/trunk/lib/CodeGen/CGOpenCLRuntime.cpp
  cfe/trunk/lib/CodeGen/CodeGenTypes.cpp
  cfe/trunk/lib/CodeGen/ItaniumCXXABI.cpp
  cfe/trunk/lib/Headers/opencl-c.h
  cfe/trunk/lib/Index/USRGeneration.cpp
  cfe/trunk/lib/Sema/Sema.cpp
  cfe/trunk/lib/Sema/SemaExpr.cpp
  cfe/trunk/lib/Sema/SemaInit.cpp
  cfe/trunk/lib/Serialization/ASTCommon.cpp
  cfe/trunk/lib/Serialization/ASTReader.cpp
  cfe/trunk/test/CodeGenOpenCL/intel-subgroups-avc-ext-types.cl
  cfe/trunk/test/Headers/opencl-c-header.cl
  cfe/trunk/test/Index/opencl-types.cl
  cfe/trunk/test/SemaOpenCL/extension-version.cl
  cfe/trunk/test/SemaOpenCL/intel-subgroup-avc-ext-types.cl
  cfe/trunk/tools/libclang/CIndex.cpp
  cfe/trunk/tools/libclang/CXType.cpp

Index: cfe/trunk/include/clang-c/Index.h
===
--- cfe/trunk/include/clang-c/Index.h
+++ cfe/trunk/include/clang-c/Index.h
@@ -3297,7 +3297,21 @@
 
   CXType_ObjCObject = 161,
   CXType_ObjCTypeParam = 162,
-  CXType_Attributed = 163
+  CXType_Attributed = 163,
+
+  CXType_OCLIntelSubgroupAVCMcePayload = 164,
+  CXType_OCLIntelSubgroupAVCImePayload = 165,
+  CXType_OCLIntelSubgroupAVCRefPayload = 166,
+  CXType_OCLIntelSubgroupAVCSicPayload = 167,
+  CXType_OCLIntelSubgroupAVCMceResult = 168,
+  CXType_OCLIntelSubgroupAVCImeResult = 169,
+  CXType_OCLIntelSubgroupAVCRefResult = 170,
+  CXType_OCLIntelSubgroupAVCSicResult = 171,
+  CXType_OCLIntelSubgroupAVCImeResultSingleRefStreamout = 172,
+  CXType_OCLIntelSubgroupAVCImeResultDualRefStreamout = 173,
+  CXType_OCLIntelSubgroupAVCImeSingleRefStreamin = 174,
+
+  CXType_OCLIntelSubgroupAVCImeDualRefStreamin = 175
 };
 
 /**
Index: cfe/trunk/include/clang/AST/ASTContext.h
===
--- cfe/trunk/include/clang/AST/ASTContext.h
+++ cfe/trunk/include/clang/AST/ASTContext.h
@@ -1062,6 +1062,9 @@
   CanQualType OCLSamplerTy, OCLEventTy, OCLClkEventTy;
   CanQualType OCLQueueTy, OCLReserveIDTy;
   CanQualType OMPArraySectionTy;
+#define EXT_OPAQUE_TYPE(ExtType, Id, Ext) \
+  CanQualType Id##Ty;
+#include "clang/Basic/OpenCLExtensionTypes.def"
 
   // Types for deductions in C++0x [stmt.ranged]'s desugaring. Built on demand.
   mutable QualType AutoDeductTy; // Deduction against 'auto'.
Index: cfe/trunk/include/clang/AST/Type.h
===
--- cfe/trunk/include/clang/AST/Type.h
+++ cfe/trunk/include/clang/AST/Type.h
@@ -2046,6 +2046,13 @@
   bool isQueueT() const;// OpenCL queue_t
   bool isReserveIDT() const;// OpenCL reserve_id_t
 
+#define EXT_OPAQUE_TYPE(ExtType, Id, Ext) \
+  bool is##Id##Type() const;
+#include "clang/Basic/OpenCLExtensionTypes.def"
+  // Type defined in cl_intel_device_side_avc_motion_estimation OpenCL extension
+  bool isOCLIntelSubgroupAVCType() const;
+  bool isOCLExtOpaqueType() const;  // Any OpenCL extension type
+
   bool isPipeType() const;  // OpenCL pipe type
   bool isOpenCLSpecificType() const;// Any OpenCL specific type
 
@@ -2393,6 +2400,9 @@
 // OpenCL image types
 #define IMAGE_TYPE(ImgType, Id, SingletonId, Access, Suffix) Id,
 #include "clang/Basic/OpenCLImageTypes.def"
+// OpenCL extension types
+#define EXT_OPAQUE_TYPE(ExtType, Id, Ext) Id,
+#include "clang/Basic/OpenCLExtensionTypes.def"
 // All other builtin types
 #define BUILTIN_TYPE(Id, SingletonId) Id,
 #define LAST_BUILTIN_TYPE(Id) LastKind = Id
@@ -6454,9 +6464,30 @@
   return isa(CanonicalType);
 }
 
+#define EXT_OPAQUE_TYPE(ExtType, Id, Ext) \
+  inline bool Type::is##Id##Type() const { \
+return isSpecificBuiltinType(BuiltinType::Id); \
+  }
+#include "clang/Basic/OpenCLExtensionTypes.def"
+

[PATCH] D54152: [OpenCL] Fix diagnostic message about overload candidates

2018-11-07 Thread Andrew Savonichev via Phabricator via cfe-commits
This revision was automatically updated to reflect the committed changes.
Closed by commit rC346311: [OpenCL] Fix diagnostic message about overload 
candidates (authored by asavonic, committed by ).

Repository:
  rC Clang

https://reviews.llvm.org/D54152

Files:
  include/clang/Basic/DiagnosticSemaKinds.td
  test/SemaOpenCL/extension-begin.cl


Index: include/clang/Basic/DiagnosticSemaKinds.td
===
--- include/clang/Basic/DiagnosticSemaKinds.td
+++ include/clang/Basic/DiagnosticSemaKinds.td
@@ -3681,7 +3681,7 @@
 def note_ovl_candidate_disabled_by_function_cond_attr : Note<
 "candidate disabled: %0">;
 def note_ovl_candidate_disabled_by_extension : Note<
-"candidate unavailable as it requires OpenCL extension '%0' to be 
disabled">;
+"candidate unavailable as it requires OpenCL extension '%0' to be 
enabled">;
 def err_addrof_function_disabled_by_enable_if_attr : Error<
 "cannot take address of function %0 because it has one or more "
 "non-tautological enable_if conditions">;
Index: test/SemaOpenCL/extension-begin.cl
===
--- test/SemaOpenCL/extension-begin.cl
+++ test/SemaOpenCL/extension-begin.cl
@@ -40,7 +40,7 @@
   PointerOfA test_A_pointer; // expected-error {{use of type 'PointerOfA' (aka 
'const struct A *') requires my_ext extension to be enabled}}
   f(); // expected-error {{use of declaration 'f' requires my_ext extension to 
be enabled}}
   g(0); // expected-error {{no matching function for call to 'g'}}
-// expected-note@extension-begin.h:18 {{candidate unavailable as it 
requires OpenCL extension 'my_ext' to be disabled}}
+// expected-note@extension-begin.h:18 {{candidate unavailable as it 
requires OpenCL extension 'my_ext' to be enabled}}
 // expected-note@extension-begin.h:23 {{candidate function not viable: 
requires 0 arguments, but 1 was provided}}
 }
 


Index: include/clang/Basic/DiagnosticSemaKinds.td
===
--- include/clang/Basic/DiagnosticSemaKinds.td
+++ include/clang/Basic/DiagnosticSemaKinds.td
@@ -3681,7 +3681,7 @@
 def note_ovl_candidate_disabled_by_function_cond_attr : Note<
 "candidate disabled: %0">;
 def note_ovl_candidate_disabled_by_extension : Note<
-"candidate unavailable as it requires OpenCL extension '%0' to be disabled">;
+"candidate unavailable as it requires OpenCL extension '%0' to be enabled">;
 def err_addrof_function_disabled_by_enable_if_attr : Error<
 "cannot take address of function %0 because it has one or more "
 "non-tautological enable_if conditions">;
Index: test/SemaOpenCL/extension-begin.cl
===
--- test/SemaOpenCL/extension-begin.cl
+++ test/SemaOpenCL/extension-begin.cl
@@ -40,7 +40,7 @@
   PointerOfA test_A_pointer; // expected-error {{use of type 'PointerOfA' (aka 'const struct A *') requires my_ext extension to be enabled}}
   f(); // expected-error {{use of declaration 'f' requires my_ext extension to be enabled}}
   g(0); // expected-error {{no matching function for call to 'g'}}
-// expected-note@extension-begin.h:18 {{candidate unavailable as it requires OpenCL extension 'my_ext' to be disabled}}
+// expected-note@extension-begin.h:18 {{candidate unavailable as it requires OpenCL extension 'my_ext' to be enabled}}
 // expected-note@extension-begin.h:23 {{candidate function not viable: requires 0 arguments, but 1 was provided}}
 }
 
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D53200: [OpenCL] Fix serialization of OpenCLExtensionDecls

2018-10-29 Thread Andrew Savonichev via Phabricator via cfe-commits
This revision was automatically updated to reflect the committed changes.
Closed by commit rC345497: [OpenCL] Fix serialization of OpenCLExtensionDecls 
(authored by asavonic, committed by ).

Repository:
  rC Clang

https://reviews.llvm.org/D53200

Files:
  lib/Serialization/ASTWriter.cpp
  test/SemaOpenCL/extension-begin.cl
  test/SemaOpenCL/extension-begin.h

Index: test/SemaOpenCL/extension-begin.h
===
--- test/SemaOpenCL/extension-begin.h
+++ test/SemaOpenCL/extension-begin.h
@@ -0,0 +1,26 @@
+#ifndef INCLUDED
+#define INCLUDED
+
+#pragma OPENCL EXTENSION all : begin
+#pragma OPENCL EXTENSION all : end
+
+#pragma OPENCL EXTENSION my_ext : begin
+
+struct A {
+  int a;
+};
+
+typedef struct A TypedefOfA;
+typedef const __private TypedefOfA* PointerOfA;
+
+void f(void);
+
+__attribute__((overloadable)) void g(long x);
+
+#pragma OPENCL EXTENSION my_ext : end
+#pragma OPENCL EXTENSION my_ext : end
+
+__attribute__((overloadable)) void g(void);
+
+#endif // INCLUDED
+
Index: test/SemaOpenCL/extension-begin.cl
===
--- test/SemaOpenCL/extension-begin.cl
+++ test/SemaOpenCL/extension-begin.cl
@@ -1,37 +1,29 @@
 // Test this without pch.
-// RUN: %clang_cc1 %s -DHEADER -DHEADER_USER -triple spir-unknown-unknown -verify -pedantic -fsyntax-only
+// RUN: %clang_cc1 %s -triple spir-unknown-unknown -verify -pedantic -fsyntax-only
 
 // Test with pch.
-// RUN: %clang_cc1 %s -DHEADER -triple spir-unknown-unknown -emit-pch -o %t -verify -pedantic
-// RUN: %clang_cc1 %s -DHEADER_USER -triple spir-unknown-unknown -include-pch %t -fsyntax-only -verify -pedantic
+// RUN: %clang_cc1 -x cl %S/extension-begin.h -triple spir-unknown-unknown -emit-pch -o %t.pch -pedantic
+// RUN: %clang_cc1 %s -triple spir-unknown-unknown -include-pch %t.pch -DIMPLICIT_INCLUDE -DUSE_PCH -fsyntax-only -verify -pedantic
 
-#if defined(HEADER) && !defined(INCLUDED)
-#define INCLUDED 
-
-#pragma OPENCL EXTENSION all : begin // expected-warning {{expected 'disable' - ignoring}}
-#pragma OPENCL EXTENSION all : end // expected-warning {{expected 'disable' - ignoring}}
-
-#pragma OPENCL EXTENSION my_ext : begin 
-
-struct A {
-  int a;
-};
-
-typedef struct A TypedefOfA;
-typedef const TypedefOfA* PointerOfA;
-
-void f(void);
-
-__attribute__((overloadable)) void g(long x);
-
-#pragma OPENCL EXTENSION my_ext : end
-#pragma OPENCL EXTENSION my_ext : end // expected-warning {{OpenCL extension end directive mismatches begin directive - ignoring}}
-
-__attribute__((overloadable)) void g(void);
-
-#endif // defined(HEADER) && !defined(INCLUDED)
-
-#ifdef HEADER_USER
+// Test with modules
+// RUN: rm -rf %t.modules
+// RUN: mkdir -p %t.modules
+//
+// RUN: %clang_cc1 -cl-std=CL1.2 -DIMPLICIT_INCLUDE -include %S/extension-begin.h -triple spir-unknown-unknown -O0 -emit-llvm -o - -fmodules -fimplicit-module-maps -fmodules-cache-path=%t.modules %s -verify -pedantic
+//
+// RUN: rm -rf %t.modules
+// RUN: mkdir -p %t.modules
+//
+// RUN: %clang_cc1 -cl-std=CL2.0 -DIMPLICIT_INCLUDE -include %S/extension-begin.h -triple spir-unknown-unknown -O0 -emit-llvm -o - -fmodules -fimplicit-module-maps -fmodules-cache-path=%t.modules %s -verify -pedantic
+
+#ifndef IMPLICIT_INCLUDE
+#include "extension-begin.h"
+#endif // IMPLICIT_INCLUDE
+#ifndef USE_PCH
+// expected-warning@extension-begin.h:4 {{expected 'disable' - ignoring}}
+// expected-warning@extension-begin.h:5 {{expected 'disable' - ignoring}}
+// expected-warning@extension-begin.h:21 {{OpenCL extension end directive mismatches begin directive - ignoring}}
+#endif // USE_PCH
 
 #pragma OPENCL EXTENSION my_ext : enable
 void test_f1(void) {
@@ -48,9 +40,7 @@
   PointerOfA test_A_pointer; // expected-error {{use of type 'PointerOfA' (aka 'const struct A *') requires my_ext extension to be enabled}}
   f(); // expected-error {{use of declaration 'f' requires my_ext extension to be enabled}}
   g(0); // expected-error {{no matching function for call to 'g'}}
-// expected-note@-26 {{candidate unavailable as it requires OpenCL extension 'my_ext' to be disabled}}
-// expected-note@-22 {{candidate function not viable: requires 0 arguments, but 1 was provided}}
+// expected-note@extension-begin.h:18 {{candidate unavailable as it requires OpenCL extension 'my_ext' to be disabled}}
+// expected-note@extension-begin.h:23 {{candidate function not viable: requires 0 arguments, but 1 was provided}}
 }
 
-#endif // HEADER_USER
-
Index: lib/Serialization/ASTWriter.cpp
===
--- lib/Serialization/ASTWriter.cpp
+++ lib/Serialization/ASTWriter.cpp
@@ -5014,13 +5014,16 @@
   WriteFPPragmaOptions(SemaRef.getFPOptions());
   WriteOpenCLExtensions(SemaRef);
   WriteOpenCLExtensionTypes(SemaRef);
-  WriteOpenCLExtensionDecls(SemaRef);
   WriteCUDAPragmas(SemaRef);
 
   // If we're emitting a module, write out the 

[PATCH] D53023: Prototype OpenCL BIFs using Tablegen

2018-10-26 Thread Andrew Savonichev via Phabricator via cfe-commits
asavonic added inline comments.



Comment at: lib/Sema/SemaExpr.cpp:2247
   if (R.empty() && HasTrailingLParen && II && !getLangOpts().CPlusPlus) {
-NamedDecl *D = ImplicitlyDefineFunction(NameLoc, *II, S);
-if (D) R.addDecl(D);
+if (getLangOpts().OpenCL) {
+  auto Index =

It will be good to have a driver option to enable this feature.


https://reviews.llvm.org/D53023



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


[PATCH] D53023: Prototype OpenCL BIFs using Tablegen

2018-10-26 Thread Andrew Savonichev via Phabricator via cfe-commits
asavonic added a comment.

> TODO
>  Measure the performance / size impact

I looks like the total size of OpenCLBuiltinDecl table should be
~450KB (for ~15000 functions). I guess it can be reduced furthermore by:

1. Replacing return type with an index (you've mentioned this in TODO).
2. Replace extension and a version with a single index.
3. Same for NumArgs and ArgTableIndex - they seem to be really tied together, 
so maybe we can use a single identifier for them?

With these improvements the total size should become ~175KB, which
seems to be ok, considering that libclangSema.so takes 9.4MB.

In my opinion, even 450KB is a vast improvement over what we have now,
because opencl-c.h alone takes 786KB.




Comment at: lib/Sema/SemaExpr.cpp:2131
+  ParmVarDecl::Create(Context, NewFD, SourceLocation(),
+  SourceLocation(), PP.getIdentifierInfo(arg_name),
+  ArgTypes[i], nullptr, SC_None, nullptr));

This dummy identifier name actually makes a diagnostic a bit weird:

t/gid.cl:3:31: error: too many arguments to function call, expected single 
argument 'a0', have 2 arguments
uint gid = get_global_id(0, 2);

It seems to be better if you pass nullptr instead:
t/gid.cl:4:31: error: too many arguments to function call, expected 1, have 
2
uint gid = get_global_id(0, 1);




https://reviews.llvm.org/D53023



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


[PATCH] D52658: [OpenCL] Remove PIPE_RESERVE_ID_VALID_BIT from opencl-c.h

2018-10-23 Thread Andrew Savonichev via Phabricator via cfe-commits
This revision was automatically updated to reflect the committed changes.
Closed by commit rL345051: [OpenCL] Remove PIPE_RESERVE_ID_VALID_BIT from 
opencl-c.h (authored by asavonic, committed by ).
Herald added a subscriber: llvm-commits.

Changed prior to commit:
  https://reviews.llvm.org/D52658?vs=167494=170688#toc

Repository:
  rL LLVM

https://reviews.llvm.org/D52658

Files:
  cfe/trunk/lib/Headers/opencl-c.h


Index: cfe/trunk/lib/Headers/opencl-c.h
===
--- cfe/trunk/lib/Headers/opencl-c.h
+++ cfe/trunk/lib/Headers/opencl-c.h
@@ -15715,7 +15715,6 @@
 
 // OpenCL v2.0 s6.13.16 - Pipe Functions
 #if __OPENCL_C_VERSION__ >= CL_VERSION_2_0
-#define PIPE_RESERVE_ID_VALID_BIT (1U << 30)
 #define CLK_NULL_RESERVE_ID (__builtin_astype(((void*)(__SIZE_MAX__)), 
reserve_id_t))
 bool __ovld is_valid_reserve_id(reserve_id_t reserve_id);
 #endif //__OPENCL_C_VERSION__ >= CL_VERSION_2_0


Index: cfe/trunk/lib/Headers/opencl-c.h
===
--- cfe/trunk/lib/Headers/opencl-c.h
+++ cfe/trunk/lib/Headers/opencl-c.h
@@ -15715,7 +15715,6 @@
 
 // OpenCL v2.0 s6.13.16 - Pipe Functions
 #if __OPENCL_C_VERSION__ >= CL_VERSION_2_0
-#define PIPE_RESERVE_ID_VALID_BIT (1U << 30)
 #define CLK_NULL_RESERVE_ID (__builtin_astype(((void*)(__SIZE_MAX__)), reserve_id_t))
 bool __ovld is_valid_reserve_id(reserve_id_t reserve_id);
 #endif //__OPENCL_C_VERSION__ >= CL_VERSION_2_0
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D51402: [OpenCL] Adding cl_intel_planar_yuv extension

2018-10-23 Thread Andrew Savonichev via Phabricator via cfe-commits
asavonic closed this revision.
asavonic added a comment.

Committed revision 345044


https://reviews.llvm.org/D51402



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


[PATCH] D52654: [OpenCL][NFC] Unify ZeroToOCL* cast types

2018-10-23 Thread Andrew Savonichev via Phabricator via cfe-commits
This revision was automatically updated to reflect the committed changes.
Closed by commit rC345038: [OpenCL][NFC] Unify ZeroToOCL* cast types (authored 
by asavonic, committed by ).

Repository:
  rC Clang

https://reviews.llvm.org/D52654

Files:
  include/clang/AST/OperationKinds.def
  include/clang/Sema/Initialization.h
  lib/AST/Expr.cpp
  lib/AST/ExprConstant.cpp
  lib/CodeGen/CGExpr.cpp
  lib/CodeGen/CGExprAgg.cpp
  lib/CodeGen/CGExprComplex.cpp
  lib/CodeGen/CGExprConstant.cpp
  lib/CodeGen/CGExprScalar.cpp
  lib/Edit/RewriteObjCFoundationAPI.cpp
  lib/Sema/SemaCast.cpp
  lib/Sema/SemaExprCXX.cpp
  lib/Sema/SemaInit.cpp
  lib/StaticAnalyzer/Core/ExprEngineC.cpp

Index: lib/CodeGen/CGExprComplex.cpp
===
--- lib/CodeGen/CGExprComplex.cpp
+++ lib/CodeGen/CGExprComplex.cpp
@@ -505,8 +505,7 @@
   case CK_ARCExtendBlockObject:
   case CK_CopyAndAutoreleaseBlockObject:
   case CK_BuiltinFnToFnPtr:
-  case CK_ZeroToOCLEvent:
-  case CK_ZeroToOCLQueue:
+  case CK_ZeroToOCLOpaqueType:
   case CK_AddressSpaceConversion:
   case CK_IntToOCLSampler:
   case CK_FixedPointCast:
Index: lib/CodeGen/CGExpr.cpp
===
--- lib/CodeGen/CGExpr.cpp
+++ lib/CodeGen/CGExpr.cpp
@@ -4254,10 +4254,8 @@
 return MakeAddrLValue(V, E->getType(), LV.getBaseInfo(),
   CGM.getTBAAInfoForSubobject(LV, E->getType()));
   }
-  case CK_ZeroToOCLQueue:
-llvm_unreachable("NULL to OpenCL queue lvalue cast is not valid");
-  case CK_ZeroToOCLEvent:
-llvm_unreachable("NULL to OpenCL event lvalue cast is not valid");
+  case CK_ZeroToOCLOpaqueType:
+llvm_unreachable("NULL to OpenCL opaque type lvalue cast is not valid");
   }
 
   llvm_unreachable("Unhandled lvalue cast kind?");
Index: lib/CodeGen/CGExprConstant.cpp
===
--- lib/CodeGen/CGExprConstant.cpp
+++ lib/CodeGen/CGExprConstant.cpp
@@ -869,9 +869,8 @@
 case CK_FloatingToIntegral:
 case CK_FloatingToBoolean:
 case CK_FloatingCast:
-case CK_ZeroToOCLEvent:
-case CK_ZeroToOCLQueue:
 case CK_FixedPointCast:
+case CK_ZeroToOCLOpaqueType:
   return nullptr;
 }
 llvm_unreachable("Invalid CastKind");
Index: lib/CodeGen/CGExprScalar.cpp
===
--- lib/CodeGen/CGExprScalar.cpp
+++ lib/CodeGen/CGExprScalar.cpp
@@ -2046,13 +2046,9 @@
  CE->getExprLoc());
   }
 
-  case CK_ZeroToOCLEvent: {
-assert(DestTy->isEventT() && "CK_ZeroToOCLEvent cast on non-event type");
-return llvm::Constant::getNullValue(ConvertType(DestTy));
-  }
-
-  case CK_ZeroToOCLQueue: {
-assert(DestTy->isQueueT() && "CK_ZeroToOCLQueue cast on non queue_t type");
+  case CK_ZeroToOCLOpaqueType: {
+assert((DestTy->isEventT() || DestTy->isQueueT()) &&
+   "CK_ZeroToOCLEvent cast on non-event type");
 return llvm::Constant::getNullValue(ConvertType(DestTy));
   }
 
Index: lib/CodeGen/CGExprAgg.cpp
===
--- lib/CodeGen/CGExprAgg.cpp
+++ lib/CodeGen/CGExprAgg.cpp
@@ -847,8 +847,7 @@
   case CK_ARCExtendBlockObject:
   case CK_CopyAndAutoreleaseBlockObject:
   case CK_BuiltinFnToFnPtr:
-  case CK_ZeroToOCLEvent:
-  case CK_ZeroToOCLQueue:
+  case CK_ZeroToOCLOpaqueType:
   case CK_AddressSpaceConversion:
   case CK_IntToOCLSampler:
   case CK_FixedPointCast:
Index: lib/StaticAnalyzer/Core/ExprEngineC.cpp
===
--- lib/StaticAnalyzer/Core/ExprEngineC.cpp
+++ lib/StaticAnalyzer/Core/ExprEngineC.cpp
@@ -412,8 +412,7 @@
   case CK_BlockPointerToObjCPointerCast:
   case CK_AnyPointerToBlockPointerCast:
   case CK_ObjCObjectLValueCast:
-  case CK_ZeroToOCLEvent:
-  case CK_ZeroToOCLQueue:
+  case CK_ZeroToOCLOpaqueType:
   case CK_IntToOCLSampler:
   case CK_LValueBitCast:
   case CK_FixedPointCast: {
Index: lib/AST/Expr.cpp
===
--- lib/AST/Expr.cpp
+++ lib/AST/Expr.cpp
@@ -1641,8 +1641,7 @@
   case CK_ARCConsumeObject:
   case CK_ARCReclaimReturnedObject:
   case CK_ARCExtendBlockObject:
-  case CK_ZeroToOCLEvent:
-  case CK_ZeroToOCLQueue:
+  case CK_ZeroToOCLOpaqueType:
   case CK_IntToOCLSampler:
   case CK_FixedPointCast:
 assert(!getType()->isBooleanType() && "unheralded conversion to bool");
Index: lib/AST/ExprConstant.cpp
===
--- lib/AST/ExprConstant.cpp
+++ lib/AST/ExprConstant.cpp
@@ -9551,8 +9551,7 @@
   case CK_IntegralComplexCast:
   case CK_IntegralComplexToFloatingComplex:
   case CK_BuiltinFnToFnPtr:
-  case CK_ZeroToOCLEvent:
-  case CK_ZeroToOCLQueue:
+  case CK_ZeroToOCLOpaqueType:
   case CK_NonAtomicToAtomic:
   case 

[PATCH] D52292: [Sema][OpenCL] Improve diagnostics for not viable overloadable function candidates

2018-10-11 Thread Andrew Savonichev via Phabricator via cfe-commits
This revision was automatically updated to reflect the committed changes.
Closed by commit rC344246: [Sema][OpenCL] Improve diagnostics for not viable 
overloadable function… (authored by asavonic, committed by ).

Repository:
  rC Clang

https://reviews.llvm.org/D52292

Files:
  include/clang/Basic/DiagnosticSemaKinds.td
  include/clang/Sema/Sema.h
  lib/Sema/Sema.cpp
  lib/Sema/SemaOverload.cpp
  test/SemaOpenCL/extension-begin.cl

Index: include/clang/Sema/Sema.h
===
--- include/clang/Sema/Sema.h
+++ include/clang/Sema/Sema.h
@@ -8576,6 +8576,21 @@
   llvm::StringRef getCurrentOpenCLExtension() const {
 return CurrOpenCLExtension;
   }
+
+  /// Check if a function declaration \p FD associates with any
+  /// extensions present in OpenCLDeclExtMap and if so return the
+  /// extension(s) name(s).
+  std::string getOpenCLExtensionsFromDeclExtMap(FunctionDecl *FD);
+
+  /// Check if a function type \p FT associates with any
+  /// extensions present in OpenCLTypeExtMap and if so return the
+  /// extension(s) name(s).
+  std::string getOpenCLExtensionsFromTypeExtMap(FunctionType *FT);
+
+  /// Find an extension in an appropriate extension map and return its name
+  template
+  std::string getOpenCLExtensionsFromExtMap(T* FT, MapT );
+
   void setCurrentOpenCLExtension(llvm::StringRef Ext) {
 CurrOpenCLExtension = Ext;
   }
Index: include/clang/Basic/DiagnosticSemaKinds.td
===
--- include/clang/Basic/DiagnosticSemaKinds.td
+++ include/clang/Basic/DiagnosticSemaKinds.td
@@ -3674,7 +3674,7 @@
 def note_ovl_candidate_disabled_by_function_cond_attr : Note<
 "candidate disabled: %0">;
 def note_ovl_candidate_disabled_by_extension : Note<
-"candidate disabled due to OpenCL extension">;
+"candidate unavailable as it requires OpenCL extension '%0' to be disabled">;
 def err_addrof_function_disabled_by_enable_if_attr : Error<
 "cannot take address of function %0 because it has one or more "
 "non-tautological enable_if conditions">;
Index: test/SemaOpenCL/extension-begin.cl
===
--- test/SemaOpenCL/extension-begin.cl
+++ test/SemaOpenCL/extension-begin.cl
@@ -48,7 +48,7 @@
   PointerOfA test_A_pointer; // expected-error {{use of type 'PointerOfA' (aka 'const struct A *') requires my_ext extension to be enabled}}
   f(); // expected-error {{use of declaration 'f' requires my_ext extension to be enabled}}
   g(0); // expected-error {{no matching function for call to 'g'}}
-// expected-note@-26 {{candidate disabled due to OpenCL extension}}
+// expected-note@-26 {{candidate unavailable as it requires OpenCL extension 'my_ext' to be disabled}}
 // expected-note@-22 {{candidate function not viable: requires 0 arguments, but 1 was provided}}
 }
 
Index: lib/Sema/SemaOverload.cpp
===
--- lib/Sema/SemaOverload.cpp
+++ lib/Sema/SemaOverload.cpp
@@ -10242,7 +10242,8 @@
   FunctionDecl *Callee = Cand->Function;
 
   S.Diag(Callee->getLocation(),
- diag::note_ovl_candidate_disabled_by_extension);
+ diag::note_ovl_candidate_disabled_by_extension)
+<< S.getOpenCLExtensionsFromDeclExtMap(Callee);
 }
 
 /// Generates a 'note' diagnostic for an overload candidate.  We've
Index: lib/Sema/Sema.cpp
===
--- lib/Sema/Sema.cpp
+++ lib/Sema/Sema.cpp
@@ -1914,6 +1914,34 @@
   setOpenCLExtensionForDecl(D, CurrOpenCLExtension);
 }
 
+std::string Sema::getOpenCLExtensionsFromDeclExtMap(FunctionDecl *FD) {
+  if (!OpenCLDeclExtMap.empty())
+return getOpenCLExtensionsFromExtMap(FD, OpenCLDeclExtMap);
+
+  return "";
+}
+
+std::string Sema::getOpenCLExtensionsFromTypeExtMap(FunctionType *FT) {
+  if (!OpenCLTypeExtMap.empty())
+return getOpenCLExtensionsFromExtMap(FT, OpenCLTypeExtMap);
+
+  return "";
+}
+
+template 
+std::string Sema::getOpenCLExtensionsFromExtMap(T *FDT, MapT ) {
+  std::string ExtensionNames = "";
+  auto Loc = Map.find(FDT);
+
+  for (auto const& I : Loc->second) {
+ExtensionNames += I;
+ExtensionNames += " ";
+  }
+  ExtensionNames.pop_back();
+
+  return ExtensionNames;
+}
+
 bool Sema::isOpenCLDisabledDecl(Decl *FD) {
   auto Loc = OpenCLDeclExtMap.find(FD);
   if (Loc == OpenCLDeclExtMap.end())
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D52458: [OpenCL] Implement OpenCL math builtins: fp -> fp

2018-09-25 Thread Andrew Savonichev via Phabricator via cfe-commits
asavonic created this revision.
Herald added subscribers: cfe-commits, kristina, Anastasia, yaxunl.

This patch adds OpenCL builtin functions that take any built-in
floating point type (float, double, half) and return a value of the
same floating point type.


Repository:
  rC Clang

https://reviews.llvm.org/D52458

Files:
  include/clang/Basic/Builtins.def
  lib/CodeGen/CGBuiltin.cpp
  lib/Sema/SemaChecking.cpp
  test/CodeGenOpenCL/builtin-math.cl
  test/SemaOpenCL/builtin-math.cl

Index: test/SemaOpenCL/builtin-math.cl
===
--- /dev/null
+++ test/SemaOpenCL/builtin-math.cl
@@ -0,0 +1,27 @@
+// RUN: %clang_cc1 -verify -pedantic -fsyntax-only -triple spir -cl-std=CL1.2 %s
+
+#pragma OPENCL EXTENSION cl_khr_fp16 : enable
+#pragma OPENCL EXTENSION cl_khr_fp64 : enable
+
+__kernel void acos_good() {
+  float i1 = 0.42f;
+  float o1 = __builtin_opencl_acos(i1);
+
+  int   i2 = 42;
+  float o2 = __builtin_opencl_acos(i2);
+
+  half  i3 = 42.0;
+  half  o3 = __builtin_opencl_acos(i3);
+
+  double i4 = 42.0;
+  double o4 = __builtin_opencl_acos(i4);
+}
+
+__kernel void acos_bad() {
+  __builtin_opencl_acos(0.0f, 0.0f); // expected-error{{too many arguments to function call, expected 1, have 2}}
+  __builtin_opencl_acos();   // expected-error{{too few arguments to function call, expected 1, have 0}}
+
+  struct {float f;} i1 = {42.0f};
+  float o1 = __builtin_opencl_acos(i1); // expected-error{{illegal call to '__builtin_opencl_acos', expected scalar or vector floating point argument type}}
+}
+
Index: test/CodeGenOpenCL/builtin-math.cl
===
--- /dev/null
+++ test/CodeGenOpenCL/builtin-math.cl
@@ -0,0 +1,24 @@
+// RUN: %clang_cc1 -triple spir -cl-std=CL1.2 -O0 -emit-llvm -o - %s | FileCheck %s
+
+#pragma OPENCL EXTENSION cl_khr_fp16 : enable
+#pragma OPENCL EXTENSION cl_khr_fp64 : enable
+
+__kernel void acos_good() {
+  float i1 = 0.42f;
+  float o1 = __builtin_opencl_acos(i1);
+  // CHECK: call float @_Z4acosf(float %{{.*}}) #[[ATTR:[0-9+]]]
+
+  int   i2 = 42;
+  float o2 = __builtin_opencl_acos(i2);
+  // CHECK: %[[INTCONV:.*]] = sitofp i32 %{{.*}} to float
+  // CHECK: call float @_Z4acosf(float %[[INTCONV]]) #[[ATTR]]
+
+  half  i3 = 42.0;
+  half  o3 = __builtin_opencl_acos(i3);
+  // CHECK: call half @_Z4acosDh(half %{{.*}}) #[[ATTR]]
+
+  double i4 = 42.0;
+  double o4 = __builtin_opencl_acos(i4);
+  // CHECK: call double @_Z4acosd(double %{{.*}}) #[[ATTR]]
+}
+
Index: lib/Sema/SemaChecking.cpp
===
--- lib/Sema/SemaChecking.cpp
+++ lib/Sema/SemaChecking.cpp
@@ -925,6 +925,106 @@
   return false;
 }
 
+static bool checkOpenCLFPScalarOrVectorArg(Sema , CallExpr *Call,
+   unsigned ArgNum) {
+  Expr *Arg = Call->getArg(0);
+
+  // Perform an implicit conversion from integer
+  if (Arg->getType()->isIntegerType()) {
+ExprResult ArgExpr(Arg);
+Sema::AssignConvertType ConvertType = S.CheckSingleAssignmentConstraints(
+S.getASTContext().FloatTy, ArgExpr);
+if (Sema::Incompatible != ConvertType) {
+  // Replace an argument with an implicit conversion to float.
+  Call->setArg(0, ArgExpr.get());
+  Arg = ArgExpr.get();
+}
+  }
+
+  QualType Ty = Arg->getType();
+
+  const BuiltinType *BaseTy = nullptr;
+  if (auto *BuiltinTy = Ty->getAs()) {
+BaseTy = BuiltinTy;
+  } else if (auto *VecTy = Ty->getAs()) {
+BaseTy = VecTy->getElementType()->getAs();
+  }
+
+  if (!BaseTy || !BaseTy->isFloatingPoint()) {
+S.Diag(Arg->getBeginLoc(), diag::err_opencl_builtin_expected_type)
+<< Call->getDirectCallee() << "scalar or vector floating point";
+return true;
+  }
+
+  return false;
+}
+
+static bool checkOpenCLMathBuiltin(Sema , unsigned BuiltinID,
+   CallExpr *Call) {
+  switch (BuiltinID) {
+  case Builtin::BI__builtin_opencl_acos:
+  case Builtin::BI__builtin_opencl_acosh:
+  case Builtin::BI__builtin_opencl_acospi:
+  case Builtin::BI__builtin_opencl_asin:
+  case Builtin::BI__builtin_opencl_asinh:
+  case Builtin::BI__builtin_opencl_asinpi:
+  case Builtin::BI__builtin_opencl_atan:
+  case Builtin::BI__builtin_opencl_atanh:
+  case Builtin::BI__builtin_opencl_atanpi:
+  case Builtin::BI__builtin_opencl_cbrt:
+  case Builtin::BI__builtin_opencl_ceil:
+  case Builtin::BI__builtin_opencl_copysign:
+  case Builtin::BI__builtin_opencl_cos:
+  case Builtin::BI__builtin_opencl_cosh:
+  case Builtin::BI__builtin_opencl_cospi:
+  case Builtin::BI__builtin_opencl_erfc:
+  case Builtin::BI__builtin_opencl_erf:
+  case Builtin::BI__builtin_opencl_exp:
+  case Builtin::BI__builtin_opencl_exp2:
+  case Builtin::BI__builtin_opencl_exp10:
+  case Builtin::BI__builtin_opencl_expm1:
+  case Builtin::BI__builtin_opencl_fabs:
+  case Builtin::BI__builtin_opencl_floor:
+  case Builtin::BI__builtin_opencl_ilogb:
+  

[PATCH] D52457: [OpenCL] Implement OpenCL convert builtin

2018-09-25 Thread Andrew Savonichev via Phabricator via cfe-commits
asavonic created this revision.
Herald added subscribers: cfe-commits, kristina, Anastasia, yaxunl.

OpenCL `convert' is a builtin that takes a builtin scalar or vector
type, and converts it to another builtin scalar or vector type using
different rounding modes (round-to-even, round-to-zero, etc.)

Previously `convert' builtin was declared in opencl-c.h header as 6284
function declarations: all combinations of types are multiplied by 10
modes.

This patch adds a single clang builtin that can codegen into any of
these 6284 builtins.

`__builtin_opencl_convert' takes 3 parameters:

1. Value to convert
2. Return type placeholder that is used to determine a result type of 
conversion.
3. Integer constant that denotes a rounding mode.


Repository:
  rC Clang

https://reviews.llvm.org/D52457

Files:
  include/clang/Basic/Builtins.def
  include/clang/Basic/DiagnosticSemaKinds.td
  lib/CodeGen/CGBuiltin.cpp
  lib/Sema/SemaChecking.cpp
  test/CodeGenOpenCL/builtin-convert.cl
  test/SemaOpenCL/builtin-convert.cl

Index: test/SemaOpenCL/builtin-convert.cl
===
--- /dev/null
+++ test/SemaOpenCL/builtin-convert.cl
@@ -0,0 +1,38 @@
+// RUN: %clang_cc1 %s -verify -pedantic -fsyntax-only
+
+typedef char char2 __attribute__((ext_vector_type(2)));
+typedef int   int2 __attribute__((ext_vector_type(2)));
+typedef int   int3 __attribute__((ext_vector_type(3)));
+
+#define __OPENCL_CONVERT_DEFAULT__ 0
+
+#define convert_char(x)  __builtin_opencl_convert((x), (char) 0, __OPENCL_CONVERT_DEFAULT__)
+#define convert_char2(x) __builtin_opencl_convert((x), (char2)0, __OPENCL_CONVERT_DEFAULT__)
+
+__kernel void good() {
+  int  i1 = 42;
+  long i2 = 43;
+  int2 i3 = 44;
+
+  char  o1 = convert_char(i1);
+  char  o2 = convert_char(i2);
+  char2 o3 = convert_char2(i3);
+}
+
+__kernel void bad(image1d_t image) {
+  __builtin_opencl_convert(1);  // expected-error{{too few arguments to function call, expected 3, have 1}}
+  __builtin_opencl_convert(1, 2, 3, 4); // expected-error{{too many arguments to function call, expected 3, have 4}}
+
+  char o1 = convert_char(image); // expected-error{{conversion is available only from OpenCL built-in scalar or vector type}}
+
+  struct st { int i; };
+  struct st i2;
+  char o2 = convert_char(i2); // expected-error{{conversion is available only from OpenCL built-in scalar or vector type}}
+
+  int2 i3 = 42;
+  char2 o3 = convert_char(i3); // expected-error{{operand and result type must have the same number of elements}}
+
+  int3 i4 = 42;
+  char2 o4 = convert_char2(i4); // expected-error{{operand and result type must have the same number of elements}}
+}
+
Index: test/CodeGenOpenCL/builtin-convert.cl
===
--- /dev/null
+++ test/CodeGenOpenCL/builtin-convert.cl
@@ -0,0 +1,69 @@
+// RUN: %clang_cc1 -emit-llvm -o - -triple spir -disable-llvm-passes %s | FileCheck %s
+
+typedef char char2 __attribute__((ext_vector_type(2)));
+typedef int   int2 __attribute__((ext_vector_type(2)));
+
+#define __OPENCL_CONVERT_DEFAULT__ 0
+#define __OPENCL_CONVERT_RTE__ 1
+#define __OPENCL_CONVERT_RTZ__ 2
+#define __OPENCL_CONVERT_RTP__ 3
+#define __OPENCL_CONVERT_RTN__ 4
+#define __OPENCL_CONVERT_SAT__ 5
+#define __OPENCL_CONVERT_SATRTE__  6
+#define __OPENCL_CONVERT_SATRTZ__  7
+#define __OPENCL_CONVERT_SATRTP__  8
+#define __OPENCL_CONVERT_SATRTN__  9
+
+#define convert_char(x)  __builtin_opencl_convert((x), (char) 0, __OPENCL_CONVERT_DEFAULT__)
+#define convert_char2(x) __builtin_opencl_convert((x), (char2)0, __OPENCL_CONVERT_DEFAULT__)
+
+#define convert_char_rte(x) __builtin_opencl_convert((x), (char) 0, __OPENCL_CONVERT_RTE__)
+#define convert_char_rtz(x) __builtin_opencl_convert((x), (char) 0, __OPENCL_CONVERT_RTZ__)
+#define convert_char_rtp(x) __builtin_opencl_convert((x), (char) 0, __OPENCL_CONVERT_RTP__)
+#define convert_char_rtn(x) __builtin_opencl_convert((x), (char) 0, __OPENCL_CONVERT_RTN__)
+#define convert_char_sat(x) __builtin_opencl_convert((x), (char) 0, __OPENCL_CONVERT_SAT__)
+#define convert_char_sat_rte(x) __builtin_opencl_convert((x), (char) 0, __OPENCL_CONVERT_SATRTE__)
+#define convert_char_sat_rtz(x) __builtin_opencl_convert((x), (char) 0, __OPENCL_CONVERT_SATRTZ__)
+#define convert_char_sat_rtp(x) __builtin_opencl_convert((x), (char) 0, __OPENCL_CONVERT_SATRTP__)
+#define convert_char_sat_rtn(x) __builtin_opencl_convert((x), (char) 0, __OPENCL_CONVERT_SATRTN__)
+
+__kernel void good() {
+  int i = 0;
+  char o;
+
+  o = convert_char_rte(i);
+  o = convert_char_rtz(i);
+  o = convert_char_rtp(i);
+  o = convert_char_rtn(i);
+  o = convert_char_sat(i);
+  o = convert_char_sat_rte(i);
+  o = convert_char_sat_rtz(i);
+  o = convert_char_sat_rtp(i);
+  o = convert_char_sat_rtn(i);
+
+  // CHECK: call signext i8 @_Z16convert_char_rtei(i32 %{{.*}})
+  // CHECK: call signext i8 @_Z16convert_char_rtzi(i32 %{{.*}})
+  // CHECK: 

[PATCH] D51722: [OpenCL] Allow blocks to capture arrays in OpenCL

2018-09-17 Thread Andrew Savonichev via Phabricator via cfe-commits
This revision was automatically updated to reflect the committed changes.
Closed by commit rL342370: [OpenCL] Allow blocks to capture arrays in OpenCL 
(authored by asavonic, committed by ).
Herald added a subscriber: llvm-commits.

Changed prior to commit:
  https://reviews.llvm.org/D51722?vs=164214=165740#toc

Repository:
  rL LLVM

https://reviews.llvm.org/D51722

Files:
  cfe/trunk/lib/Sema/SemaExpr.cpp
  cfe/trunk/test/SemaOpenCL/block-array-capturing.cl


Index: cfe/trunk/test/SemaOpenCL/block-array-capturing.cl
===
--- cfe/trunk/test/SemaOpenCL/block-array-capturing.cl
+++ cfe/trunk/test/SemaOpenCL/block-array-capturing.cl
@@ -0,0 +1,16 @@
+// RUN: %clang_cc1 -O0 -cl-std=CL2.0 -triple spir64-unkown-unkown -emit-llvm 
%s -o -| FileCheck %s
+// expected-no-diagnostics
+
+typedef int (^block_t)();
+
+int block_typedef_kernel(global int* res) {
+  // CHECK: %{{.*}} = alloca <{ i32, i32, [3 x i32] }>
+  int a[3] = {1, 2, 3};
+  // CHECK: call void @llvm.memcpy{{.*}}
+  block_t b = ^() { return a[0]; };
+  return b();
+}
+
+// CHECK: define {{.*}} @__block_typedef_kernel_block_invoke
+// CHECK: %{{.*}} = getelementptr inbounds [3 x i32], [3 x i32] addrspace(4)* 
%{{.*}}, i64 0, i64 0
+// CHECK-NOT: call void @llvm.memcpy{{.*}}
Index: cfe/trunk/lib/Sema/SemaExpr.cpp
===
--- cfe/trunk/lib/Sema/SemaExpr.cpp
+++ cfe/trunk/lib/Sema/SemaExpr.cpp
@@ -14627,8 +14627,10 @@
   Expr *CopyExpr = nullptr;
   bool ByRef = false;
 
-  // Blocks are not allowed to capture arrays.
-  if (CaptureType->isArrayType()) {
+  // Blocks are not allowed to capture arrays, excepting OpenCL.
+  // OpenCL v2.0 s1.12.5 (revision 40): arrays are captured by reference
+  // (decayed to pointers).
+  if (!S.getLangOpts().OpenCL && CaptureType->isArrayType()) {
 if (BuildAndDiagnose) {
   S.Diag(Loc, diag::err_ref_array_type);
   S.Diag(Var->getLocation(), diag::note_previous_decl)


Index: cfe/trunk/test/SemaOpenCL/block-array-capturing.cl
===
--- cfe/trunk/test/SemaOpenCL/block-array-capturing.cl
+++ cfe/trunk/test/SemaOpenCL/block-array-capturing.cl
@@ -0,0 +1,16 @@
+// RUN: %clang_cc1 -O0 -cl-std=CL2.0 -triple spir64-unkown-unkown -emit-llvm %s -o -| FileCheck %s
+// expected-no-diagnostics
+
+typedef int (^block_t)();
+
+int block_typedef_kernel(global int* res) {
+  // CHECK: %{{.*}} = alloca <{ i32, i32, [3 x i32] }>
+  int a[3] = {1, 2, 3};
+  // CHECK: call void @llvm.memcpy{{.*}}
+  block_t b = ^() { return a[0]; };
+  return b();
+}
+
+// CHECK: define {{.*}} @__block_typedef_kernel_block_invoke
+// CHECK: %{{.*}} = getelementptr inbounds [3 x i32], [3 x i32] addrspace(4)* %{{.*}}, i64 0, i64 0
+// CHECK-NOT: call void @llvm.memcpy{{.*}}
Index: cfe/trunk/lib/Sema/SemaExpr.cpp
===
--- cfe/trunk/lib/Sema/SemaExpr.cpp
+++ cfe/trunk/lib/Sema/SemaExpr.cpp
@@ -14627,8 +14627,10 @@
   Expr *CopyExpr = nullptr;
   bool ByRef = false;
 
-  // Blocks are not allowed to capture arrays.
-  if (CaptureType->isArrayType()) {
+  // Blocks are not allowed to capture arrays, excepting OpenCL.
+  // OpenCL v2.0 s1.12.5 (revision 40): arrays are captured by reference
+  // (decayed to pointers).
+  if (!S.getLangOpts().OpenCL && CaptureType->isArrayType()) {
 if (BuildAndDiagnose) {
   S.Diag(Loc, diag::err_ref_array_type);
   S.Diag(Var->getLocation(), diag::note_previous_decl)
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D51853: Merge two attribute diagnostics into one

2018-09-17 Thread Andrew Savonichev via Phabricator via cfe-commits
This revision was automatically updated to reflect the committed changes.
Closed by commit rC342367: Merge two attribute diagnostics into one (authored 
by asavonic, committed by ).

Changed prior to commit:
  https://reviews.llvm.org/D51853?vs=164651=165734#toc

Repository:
  rC Clang

https://reviews.llvm.org/D51853

Files:
  include/clang/Basic/DiagnosticSemaKinds.td
  lib/Sema/SemaDeclAttr.cpp
  lib/Sema/SemaStmtAttr.cpp
  test/SemaOpenCL/invalid-kernel-attrs.cl


Index: test/SemaOpenCL/invalid-kernel-attrs.cl
===
--- test/SemaOpenCL/invalid-kernel-attrs.cl
+++ test/SemaOpenCL/invalid-kernel-attrs.cl
@@ -38,8 +38,8 @@
 kernel __attribute__((intel_reqd_sub_group_size(0))) void kernel15(){} // 
expected-error {{'intel_reqd_sub_group_size' attribute must be greater than 0}}
 kernel __attribute__((intel_reqd_sub_group_size(8))) 
__attribute__((intel_reqd_sub_group_size(16))) void kernel16() {}  
//expected-warning{{attribute 'intel_reqd_sub_group_size' is already applied 
with different parameters}}
 
-__kernel __attribute__((work_group_size_hint(8,-16,32))) void neg1() {} 
//expected-error{{negative argument is not allowed for 'work_group_size_hint' 
attribute}}
-__kernel __attribute__((reqd_work_group_size(8,16,-32))) void neg2(){} // 
expected-error{{negative argument is not allowed for 'reqd_work_group_size' 
attribute}}
+__kernel __attribute__((work_group_size_hint(8,-16,32))) void neg1() {} 
//expected-error{{'work_group_size_hint' attribute requires a non-negative 
integral compile time constant expression}}
+__kernel __attribute__((reqd_work_group_size(8,16,-32))) void neg2(){} // 
expected-error{{'reqd_work_group_size' attribute requires a non-negative 
integral compile time constant expression}}
 
 // 4294967294 is a negative integer if treated as signed.
 // Should compile successfully, since we expect an unsigned.
Index: lib/Sema/SemaStmtAttr.cpp
===
--- lib/Sema/SemaStmtAttr.cpp
+++ lib/Sema/SemaStmtAttr.cpp
@@ -304,7 +304,7 @@
 if (Val <= 0) {
   S.Diag(A.getRange().getBegin(),
  diag::err_attribute_requires_positive_integer)
-  << A;
+  << A << /* positive */ 0;
   return nullptr;
 }
 UnrollFactor = Val;
Index: lib/Sema/SemaDeclAttr.cpp
===
--- lib/Sema/SemaDeclAttr.cpp
+++ lib/Sema/SemaDeclAttr.cpp
@@ -254,7 +254,8 @@
   }
 
   if (StrictlyUnsigned && I.isSigned() && I.isNegative()) {
-S.Diag(getAttrLoc(AI), diag::err_attribute_argument_negative) << AI;
+S.Diag(getAttrLoc(AI), diag::err_attribute_requires_positive_integer)
+<< AI << /*non-negative*/ 1;
 return false;
   }
 
Index: include/clang/Basic/DiagnosticSemaKinds.td
===
--- include/clang/Basic/DiagnosticSemaKinds.td
+++ include/clang/Basic/DiagnosticSemaKinds.td
@@ -2498,7 +2498,8 @@
 def err_attribute_bad_neon_vector_size : Error<
   "Neon vector size must be 64 or 128 bits">;
 def err_attribute_requires_positive_integer : Error<
-  "%0 attribute requires a positive integral compile time constant 
expression">;
+  "%0 attribute requires a %select{positive|non-negative}1 "
+  "integral compile time constant expression">;
 def err_attribute_requires_opencl_version : Error<
   "%0 attribute requires OpenCL version %1%select{| or above}2">;
 def warn_unsupported_target_attribute
@@ -2531,8 +2532,6 @@
   "constant|a string|an identifier}1">;
 def err_attribute_argument_outof_range : Error<
   "%0 attribute requires integer constant between %1 and %2 inclusive">;
-def err_attribute_argument_negative : Error<
-  "negative argument is not allowed for %0 attribute">;
 def err_init_priority_object_attr : Error<
   "can only use 'init_priority' attribute on file-scope definitions "
   "of objects of class type">;


Index: test/SemaOpenCL/invalid-kernel-attrs.cl
===
--- test/SemaOpenCL/invalid-kernel-attrs.cl
+++ test/SemaOpenCL/invalid-kernel-attrs.cl
@@ -38,8 +38,8 @@
 kernel __attribute__((intel_reqd_sub_group_size(0))) void kernel15(){} // expected-error {{'intel_reqd_sub_group_size' attribute must be greater than 0}}
 kernel __attribute__((intel_reqd_sub_group_size(8))) __attribute__((intel_reqd_sub_group_size(16))) void kernel16() {}  //expected-warning{{attribute 'intel_reqd_sub_group_size' is already applied with different parameters}}
 
-__kernel __attribute__((work_group_size_hint(8,-16,32))) void neg1() {} //expected-error{{negative argument is not allowed for 'work_group_size_hint' attribute}}
-__kernel __attribute__((reqd_work_group_size(8,16,-32))) void neg2(){} // expected-error{{negative argument is not allowed for 'reqd_work_group_size' attribute}}
+__kernel __attribute__((work_group_size_hint(8,-16,32))) void neg1() {} 

[PATCH] D51544: [OpenCL] Split opencl-c.h header

2018-09-11 Thread Andrew Savonichev via Phabricator via cfe-commits
asavonic added a comment.

In https://reviews.llvm.org/D51544#1229105, @Anastasia wrote:

> > With this setup, we can compile opencl-c-common.h, opencl-c-fp16.h and
> >  opencl-c-fp64.h into PCHs with one set of extensions/OpenCL version,
> >  and use them for any other set of extensions/OpenCL version. Clang
> >  will detect this and throw out an error, which can be safely disabled
> >  by -fno-validate-pch option.
>
> However, keeping this as a permanent solution is unsafe. Because this way can 
> result in unexpected errors to be silent out and allow erroneous 
> configurations to be accepted successfully without any notification.


Agree. LIT test in `test/Headers/opencl-c-header-split.cl` is supposed
to verify that common/fp16/fp64 headers do not use preprocessor macros
and it should catch most of the issues, but this is definitely not the
most robust solution.

> So I am wondering if there is any plan to put a proper solution in place at 
> some point?

This solution can be improved if we implement `convert` and `shuffle`
as clang builtins with custom typechecking: these two builtins (with
all their overloadings) take ~90% of `opencl-c-common.h` and ~50% of
fp16/fp64 headers.

However, this can be a non-trivial change: it is difficult to do a
proper mangling for clang builtins and rounding modes must be handled
as well.

I'll take a few days to prototype this. If it turns out to be good in
terms of performance/footprint, we can drop this patch.


Repository:
  rC Clang

https://reviews.llvm.org/D51544



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


[PATCH] D51853: Merge two attribute diagnostics into one

2018-09-10 Thread Andrew Savonichev via Phabricator via cfe-commits
asavonic created this revision.
asavonic added a reviewer: aaron.ballman.
Herald added a subscriber: cfe-commits.

Merged the recently added `err_attribute_argument_negative` diagnostic
with existing `err_attribute_requires_positive_integer` diagnostic:
the former allows only strictly positive integer, while the latter
also allows zero.


Repository:
  rC Clang

https://reviews.llvm.org/D51853

Files:
  include/clang/Basic/DiagnosticSemaKinds.td
  lib/Sema/SemaDeclAttr.cpp
  lib/Sema/SemaStmtAttr.cpp
  test/SemaOpenCL/invalid-kernel-attrs.cl


Index: test/SemaOpenCL/invalid-kernel-attrs.cl
===
--- test/SemaOpenCL/invalid-kernel-attrs.cl
+++ test/SemaOpenCL/invalid-kernel-attrs.cl
@@ -38,8 +38,8 @@
 kernel __attribute__((intel_reqd_sub_group_size(0))) void kernel15(){} // 
expected-error {{'intel_reqd_sub_group_size' attribute must be greater than 0}}
 kernel __attribute__((intel_reqd_sub_group_size(8))) 
__attribute__((intel_reqd_sub_group_size(16))) void kernel16() {}  
//expected-warning{{attribute 'intel_reqd_sub_group_size' is already applied 
with different parameters}}
 
-__kernel __attribute__((work_group_size_hint(8,-16,32))) void neg1() {} 
//expected-error{{negative argument is not allowed for 'work_group_size_hint' 
attribute}}
-__kernel __attribute__((reqd_work_group_size(8,16,-32))) void neg2(){} // 
expected-error{{negative argument is not allowed for 'reqd_work_group_size' 
attribute}}
+__kernel __attribute__((work_group_size_hint(8,-16,32))) void neg1() {} 
//expected-error{{'work_group_size_hint' attribute requires a non-negative 
integral compile time constant expression}}
+__kernel __attribute__((reqd_work_group_size(8,16,-32))) void neg2(){} // 
expected-error{{'reqd_work_group_size' attribute requires a non-negative 
integral compile time constant expression}}
 
 // 4294967294 is a negative integer if treated as signed.
 // Should compile successfully, since we expect an unsigned.
Index: lib/Sema/SemaStmtAttr.cpp
===
--- lib/Sema/SemaStmtAttr.cpp
+++ lib/Sema/SemaStmtAttr.cpp
@@ -304,7 +304,7 @@
 if (Val <= 0) {
   S.Diag(A.getRange().getBegin(),
  diag::err_attribute_requires_positive_integer)
-  << A;
+  << A << /* positive */ 0;
   return nullptr;
 }
 UnrollFactor = Val;
Index: lib/Sema/SemaDeclAttr.cpp
===
--- lib/Sema/SemaDeclAttr.cpp
+++ lib/Sema/SemaDeclAttr.cpp
@@ -254,7 +254,8 @@
   }
 
   if (StrictlyUnsigned && I.isSigned() && I.isNegative()) {
-S.Diag(getAttrLoc(AI), diag::err_attribute_argument_negative) << AI;
+S.Diag(getAttrLoc(AI), diag::err_attribute_requires_positive_integer)
+<< AI << /*non-negative*/ 1;
 return false;
   }
 
Index: include/clang/Basic/DiagnosticSemaKinds.td
===
--- include/clang/Basic/DiagnosticSemaKinds.td
+++ include/clang/Basic/DiagnosticSemaKinds.td
@@ -2497,7 +2497,8 @@
 def err_attribute_bad_neon_vector_size : Error<
   "Neon vector size must be 64 or 128 bits">;
 def err_attribute_requires_positive_integer : Error<
-  "%0 attribute requires a positive integral compile time constant 
expression">;
+  "%0 attribute requires a %select{positive|non-negative}1 "
+  "integral compile time constant expression">;
 def err_attribute_requires_opencl_version : Error<
   "%0 attribute requires OpenCL version %1%select{| or above}2">;
 def warn_unsupported_target_attribute
@@ -2530,8 +2531,6 @@
   "constant|a string|an identifier}1">;
 def err_attribute_argument_outof_range : Error<
   "%0 attribute requires integer constant between %1 and %2 inclusive">;
-def err_attribute_argument_negative : Error<
-  "negative argument is not allowed for %0 attribute">;
 def err_init_priority_object_attr : Error<
   "can only use 'init_priority' attribute on file-scope definitions "
   "of objects of class type">;


Index: test/SemaOpenCL/invalid-kernel-attrs.cl
===
--- test/SemaOpenCL/invalid-kernel-attrs.cl
+++ test/SemaOpenCL/invalid-kernel-attrs.cl
@@ -38,8 +38,8 @@
 kernel __attribute__((intel_reqd_sub_group_size(0))) void kernel15(){} // expected-error {{'intel_reqd_sub_group_size' attribute must be greater than 0}}
 kernel __attribute__((intel_reqd_sub_group_size(8))) __attribute__((intel_reqd_sub_group_size(16))) void kernel16() {}  //expected-warning{{attribute 'intel_reqd_sub_group_size' is already applied with different parameters}}
 
-__kernel __attribute__((work_group_size_hint(8,-16,32))) void neg1() {} //expected-error{{negative argument is not allowed for 'work_group_size_hint' attribute}}
-__kernel __attribute__((reqd_work_group_size(8,16,-32))) void neg2(){} // expected-error{{negative argument is not allowed for 'reqd_work_group_size' attribute}}
+__kernel 

[PATCH] D51544: [OpenCL] Split opencl-c.h header

2018-09-07 Thread Andrew Savonichev via Phabricator via cfe-commits
asavonic added a comment.

In https://reviews.llvm.org/D51544#1227313, @Anastasia wrote:

> Currently the main header still contains everything, so the size of the PCH 
> won't change.


The idea is that we don't pre-compile the whole opencl-c.h, we split
it into several headers (3 of them are target independent) and
pre-compile them instead.

With this approach, we can reuse target-independent PCHs (common,
fp16, fp64) and only duplicate target-specific PCHs if needed
(opencl-c-platform.h).

The idea is basically:

1. Compile target-independent headers into modules:
  - opencl-c-common.h -> opencl-c-common.pcm
  - opencl-c-fp16.h -> opencl-c-fp16.pcm
  - opencl-c-fp64.h -> opencl-c-fp64.pcm

2. Implicitly include opencl-c.h (plain header), which has the following 
content:



  #include "opencl-c-common.h"
  #if cl_khr_fp16
  #include "opencl-c-fp16.h"
  #endif
  #if cl_khr_fp64
  #include "opencl-c-fp16.h"
  #endif
  #include "opencl-c-platform.h"

When compiler reaches an #include statement in opencl-c.h, it loads a
corresponding PCH. Headers that were not pre-compiled are included as
usual.


Repository:
  rC Clang

https://reviews.llvm.org/D51544



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


[PATCH] D51302: [OpenCL] Relax diagnostics on OpenCL access qualifiers

2018-09-06 Thread Andrew Savonichev via Phabricator via cfe-commits
This revision was automatically updated to reflect the committed changes.
Closed by commit rL341553: [OpenCL] Relax diagnostics on OpenCL access 
qualifiers (authored by asavonic, committed by ).
Herald added a subscriber: llvm-commits.

Changed prior to commit:
  https://reviews.llvm.org/D51302?vs=163086=164222#toc

Repository:
  rL LLVM

https://reviews.llvm.org/D51302

Files:
  cfe/trunk/lib/Sema/SemaDeclAttr.cpp
  cfe/trunk/lib/Sema/SemaType.cpp
  cfe/trunk/test/SemaOpenCL/access-qualifier.cl

Index: cfe/trunk/test/SemaOpenCL/access-qualifier.cl
===
--- cfe/trunk/test/SemaOpenCL/access-qualifier.cl
+++ cfe/trunk/test/SemaOpenCL/access-qualifier.cl
@@ -60,7 +60,7 @@
 
 kernel void k11(read_only write_only image1d_t i){} // expected-error{{multiple access qualifiers}}
 
-kernel void k12(read_only read_only image1d_t i){} // expected-error{{multiple access qualifiers}}
+kernel void k12(read_only read_only image1d_t i){} // expected-warning {{duplicate 'read_only' declaration specifier}}
 
 #if __OPENCL_C_VERSION__ >= 200
 kernel void k13(read_write pipe int i){} // expected-error{{access qualifier 'read_write' can not be used for 'read_only pipe int'}}
@@ -78,3 +78,33 @@
 #if __OPENCL_C_VERSION__ < 200
 kernel void test_image3d_wo(write_only image3d_t img) {} // expected-error {{use of type '__write_only image3d_t' requires cl_khr_3d_image_writes extension to be enabled}}
 #endif
+
+#if __OPENCL_C_VERSION__ >= 200
+kernel void read_write_twice_typedef(read_write img1d_rw i){} // expected-warning {{duplicate 'read_write' declaration specifier}}
+// expected-note@-74 {{previously declared 'read_write' here}}
+
+kernel void pipe_ro_twice(read_only read_only pipe int i){} // expected-warning{{duplicate 'read_only' declaration specifier}}
+// Conflicting access qualifiers
+kernel void pipe_ro_twice_tw(read_write read_only read_only pipe int i){} // expected-error{{access qualifier 'read_write' can not be used for 'read_only pipe int'}}
+kernel void pipe_ro_wo(read_only write_only pipe int i){} // expected-error{{multiple access qualifiers}}
+
+typedef read_only pipe int ROPipeInt;
+kernel void pipe_ro_twice_typedef(read_only ROPipeInt i){} // expected-warning{{duplicate 'read_only' declaration specifier}}
+// expected-note@-2 {{previously declared 'read_only' here}}
+
+kernel void pass_ro_typedef_to_wo(ROPipeInt p) {
+  myPipeWrite(p); // expected-error {{passing 'ROPipeInt' (aka 'read_only pipe int') to parameter of incompatible type 'write_only pipe int'}}
+  // expected-note@-25 {{passing argument to parameter here}}
+}
+#endif
+
+kernel void read_only_twice_typedef(__read_only img1d_ro i){} // expected-warning {{duplicate '__read_only' declaration specifier}}
+// expected-note@-95 {{previously declared 'read_only' here}}
+
+kernel void read_only_twice_default(read_only img1d_ro_default img){} // expected-warning {{duplicate 'read_only' declaration specifier}}
+// expected-note@-101 {{previously declared 'read_only' here}}
+
+kernel void image_wo_twice(write_only __write_only image1d_t i){} // expected-warning {{duplicate '__write_only' declaration specifier}}
+kernel void image_wo_twice_typedef(write_only img1d_wo i){} // expected-warning {{duplicate 'write_only' declaration specifier}}
+// expected-note@-103 {{previously declared 'write_only' here}}
+
Index: cfe/trunk/lib/Sema/SemaType.cpp
===
--- cfe/trunk/lib/Sema/SemaType.cpp
+++ cfe/trunk/lib/Sema/SemaType.cpp
@@ -7105,23 +7105,43 @@
   }
 
   if (const TypedefType* TypedefTy = CurType->getAs()) {
-QualType PointeeTy = TypedefTy->desugar();
-S.Diag(Attr.getLoc(), diag::err_opencl_multiple_access_qualifiers);
+QualType BaseTy = TypedefTy->desugar();
 
 std::string PrevAccessQual;
-switch (cast(PointeeTy.getTypePtr())->getKind()) {
-  #define IMAGE_TYPE(ImgType, Id, SingletonId, Access, Suffix) \
-case BuiltinType::Id:  \
-  PrevAccessQual = #Access;\
-  break;
-  #include "clang/Basic/OpenCLImageTypes.def"
-default:
-  assert(0 && "Unable to find corresponding image type.");
+if (BaseTy->isPipeType()) {
+  if (TypedefTy->getDecl()->hasAttr()) {
+OpenCLAccessAttr *Attr =
+TypedefTy->getDecl()->getAttr();
+PrevAccessQual = Attr->getSpelling();
+  } else {
+PrevAccessQual = "read_only";
+  }
+} else if (const BuiltinType* ImgType = BaseTy->getAs()) {
+
+  switch (ImgType->getKind()) {
+#define IMAGE_TYPE(ImgType, Id, SingletonId, Access, Suffix) \
+  case BuiltinType::Id:  \
+PrevAccessQual = #Access;\
+break;
+#include "clang/Basic/OpenCLImageTypes.def"
+  default:
+llvm_unreachable("Unable to find corresponding image 

[PATCH] D51302: [OpenCL] Relax diagnostics on OpenCL access qualifiers

2018-09-06 Thread Andrew Savonichev via Phabricator via cfe-commits
This revision was automatically updated to reflect the committed changes.
Closed by commit rC341553: [OpenCL] Relax diagnostics on OpenCL access 
qualifiers (authored by asavonic, committed by ).

Repository:
  rC Clang

https://reviews.llvm.org/D51302

Files:
  lib/Sema/SemaDeclAttr.cpp
  lib/Sema/SemaType.cpp
  test/SemaOpenCL/access-qualifier.cl

Index: test/SemaOpenCL/access-qualifier.cl
===
--- test/SemaOpenCL/access-qualifier.cl
+++ test/SemaOpenCL/access-qualifier.cl
@@ -60,7 +60,7 @@
 
 kernel void k11(read_only write_only image1d_t i){} // expected-error{{multiple access qualifiers}}
 
-kernel void k12(read_only read_only image1d_t i){} // expected-error{{multiple access qualifiers}}
+kernel void k12(read_only read_only image1d_t i){} // expected-warning {{duplicate 'read_only' declaration specifier}}
 
 #if __OPENCL_C_VERSION__ >= 200
 kernel void k13(read_write pipe int i){} // expected-error{{access qualifier 'read_write' can not be used for 'read_only pipe int'}}
@@ -78,3 +78,33 @@
 #if __OPENCL_C_VERSION__ < 200
 kernel void test_image3d_wo(write_only image3d_t img) {} // expected-error {{use of type '__write_only image3d_t' requires cl_khr_3d_image_writes extension to be enabled}}
 #endif
+
+#if __OPENCL_C_VERSION__ >= 200
+kernel void read_write_twice_typedef(read_write img1d_rw i){} // expected-warning {{duplicate 'read_write' declaration specifier}}
+// expected-note@-74 {{previously declared 'read_write' here}}
+
+kernel void pipe_ro_twice(read_only read_only pipe int i){} // expected-warning{{duplicate 'read_only' declaration specifier}}
+// Conflicting access qualifiers
+kernel void pipe_ro_twice_tw(read_write read_only read_only pipe int i){} // expected-error{{access qualifier 'read_write' can not be used for 'read_only pipe int'}}
+kernel void pipe_ro_wo(read_only write_only pipe int i){} // expected-error{{multiple access qualifiers}}
+
+typedef read_only pipe int ROPipeInt;
+kernel void pipe_ro_twice_typedef(read_only ROPipeInt i){} // expected-warning{{duplicate 'read_only' declaration specifier}}
+// expected-note@-2 {{previously declared 'read_only' here}}
+
+kernel void pass_ro_typedef_to_wo(ROPipeInt p) {
+  myPipeWrite(p); // expected-error {{passing 'ROPipeInt' (aka 'read_only pipe int') to parameter of incompatible type 'write_only pipe int'}}
+  // expected-note@-25 {{passing argument to parameter here}}
+}
+#endif
+
+kernel void read_only_twice_typedef(__read_only img1d_ro i){} // expected-warning {{duplicate '__read_only' declaration specifier}}
+// expected-note@-95 {{previously declared 'read_only' here}}
+
+kernel void read_only_twice_default(read_only img1d_ro_default img){} // expected-warning {{duplicate 'read_only' declaration specifier}}
+// expected-note@-101 {{previously declared 'read_only' here}}
+
+kernel void image_wo_twice(write_only __write_only image1d_t i){} // expected-warning {{duplicate '__write_only' declaration specifier}}
+kernel void image_wo_twice_typedef(write_only img1d_wo i){} // expected-warning {{duplicate 'write_only' declaration specifier}}
+// expected-note@-103 {{previously declared 'write_only' here}}
+
Index: lib/Sema/SemaType.cpp
===
--- lib/Sema/SemaType.cpp
+++ lib/Sema/SemaType.cpp
@@ -7105,23 +7105,43 @@
   }
 
   if (const TypedefType* TypedefTy = CurType->getAs()) {
-QualType PointeeTy = TypedefTy->desugar();
-S.Diag(Attr.getLoc(), diag::err_opencl_multiple_access_qualifiers);
+QualType BaseTy = TypedefTy->desugar();
 
 std::string PrevAccessQual;
-switch (cast(PointeeTy.getTypePtr())->getKind()) {
-  #define IMAGE_TYPE(ImgType, Id, SingletonId, Access, Suffix) \
-case BuiltinType::Id:  \
-  PrevAccessQual = #Access;\
-  break;
-  #include "clang/Basic/OpenCLImageTypes.def"
-default:
-  assert(0 && "Unable to find corresponding image type.");
+if (BaseTy->isPipeType()) {
+  if (TypedefTy->getDecl()->hasAttr()) {
+OpenCLAccessAttr *Attr =
+TypedefTy->getDecl()->getAttr();
+PrevAccessQual = Attr->getSpelling();
+  } else {
+PrevAccessQual = "read_only";
+  }
+} else if (const BuiltinType* ImgType = BaseTy->getAs()) {
+
+  switch (ImgType->getKind()) {
+#define IMAGE_TYPE(ImgType, Id, SingletonId, Access, Suffix) \
+  case BuiltinType::Id:  \
+PrevAccessQual = #Access;\
+break;
+#include "clang/Basic/OpenCLImageTypes.def"
+  default:
+llvm_unreachable("Unable to find corresponding image type.");
+  }
+} else {
+  llvm_unreachable("unexpected type");
+}
+StringRef AttrName = Attr.getName()->getName();
+if (PrevAccessQual == AttrName.ltrim("_")) {
+  // Duplicated qualifiers

[PATCH] D50259: [OpenCL] Disallow negative attribute arguments

2018-09-06 Thread Andrew Savonichev via Phabricator via cfe-commits
This revision was automatically updated to reflect the committed changes.
Closed by commit rC341539: [OpenCL] Disallow negative attribute arguments 
(authored by asavonic, committed by ).

Changed prior to commit:
  https://reviews.llvm.org/D50259?vs=159022=164190#toc

Repository:
  rC Clang

https://reviews.llvm.org/D50259

Files:
  include/clang/Basic/DiagnosticSemaKinds.td
  lib/Sema/SemaDeclAttr.cpp
  test/SemaOpenCL/invalid-kernel-attrs.cl


Index: lib/Sema/SemaDeclAttr.cpp
===
--- lib/Sema/SemaDeclAttr.cpp
+++ lib/Sema/SemaDeclAttr.cpp
@@ -227,9 +227,13 @@
 
 /// If Expr is a valid integer constant, get the value of the integer
 /// expression and return success or failure. May output an error.
+///
+/// Negative argument is implicitly converted to unsigned, unless
+/// \p StrictlyUnsigned is true.
 template 
 static bool checkUInt32Argument(Sema , const AttrInfo , const Expr *Expr,
-uint32_t , unsigned Idx = UINT_MAX) {
+uint32_t , unsigned Idx = UINT_MAX,
+bool StrictlyUnsigned = false) {
   llvm::APSInt I(32);
   if (Expr->isTypeDependent() || Expr->isValueDependent() ||
   !Expr->isIntegerConstantExpr(I, S.Context)) {
@@ -249,6 +253,11 @@
 return false;
   }
 
+  if (StrictlyUnsigned && I.isSigned() && I.isNegative()) {
+S.Diag(getAttrLoc(AI), diag::err_attribute_argument_negative) << AI;
+return false;
+  }
+
   Val = (uint32_t)I.getZExtValue();
   return true;
 }
@@ -2766,7 +2775,8 @@
   uint32_t WGSize[3];
   for (unsigned i = 0; i < 3; ++i) {
 const Expr *E = AL.getArgAsExpr(i);
-if (!checkUInt32Argument(S, AL, E, WGSize[i], i))
+if (!checkUInt32Argument(S, AL, E, WGSize[i], i,
+ /*StrictlyUnsigned=*/true))
   return;
 if (WGSize[i] == 0) {
   S.Diag(AL.getLoc(), diag::err_attribute_argument_is_zero)
Index: include/clang/Basic/DiagnosticSemaKinds.td
===
--- include/clang/Basic/DiagnosticSemaKinds.td
+++ include/clang/Basic/DiagnosticSemaKinds.td
@@ -2529,6 +2529,8 @@
   "constant|a string|an identifier}1">;
 def err_attribute_argument_outof_range : Error<
   "%0 attribute requires integer constant between %1 and %2 inclusive">;
+def err_attribute_argument_negative : Error<
+  "negative argument is not allowed for %0 attribute">;
 def err_init_priority_object_attr : Error<
   "can only use 'init_priority' attribute on file-scope definitions "
   "of objects of class type">;
Index: test/SemaOpenCL/invalid-kernel-attrs.cl
===
--- test/SemaOpenCL/invalid-kernel-attrs.cl
+++ test/SemaOpenCL/invalid-kernel-attrs.cl
@@ -37,3 +37,10 @@
 __attribute__((intel_reqd_sub_group_size(8))) void kernel14(){} // 
expected-error {{attribute 'intel_reqd_sub_group_size' can only be applied to 
an OpenCL kernel}}
 kernel __attribute__((intel_reqd_sub_group_size(0))) void kernel15(){} // 
expected-error {{'intel_reqd_sub_group_size' attribute must be greater than 0}}
 kernel __attribute__((intel_reqd_sub_group_size(8))) 
__attribute__((intel_reqd_sub_group_size(16))) void kernel16() {}  
//expected-warning{{attribute 'intel_reqd_sub_group_size' is already applied 
with different parameters}}
+
+__kernel __attribute__((work_group_size_hint(8,-16,32))) void neg1() {} 
//expected-error{{negative argument is not allowed for 'work_group_size_hint' 
attribute}}
+__kernel __attribute__((reqd_work_group_size(8,16,-32))) void neg2(){} // 
expected-error{{negative argument is not allowed for 'reqd_work_group_size' 
attribute}}
+
+// 4294967294 is a negative integer if treated as signed.
+// Should compile successfully, since we expect an unsigned.
+__kernel __attribute__((reqd_work_group_size(8,16,4294967294))) void ok1(){}


Index: lib/Sema/SemaDeclAttr.cpp
===
--- lib/Sema/SemaDeclAttr.cpp
+++ lib/Sema/SemaDeclAttr.cpp
@@ -227,9 +227,13 @@
 
 /// If Expr is a valid integer constant, get the value of the integer
 /// expression and return success or failure. May output an error.
+///
+/// Negative argument is implicitly converted to unsigned, unless
+/// \p StrictlyUnsigned is true.
 template 
 static bool checkUInt32Argument(Sema , const AttrInfo , const Expr *Expr,
-uint32_t , unsigned Idx = UINT_MAX) {
+uint32_t , unsigned Idx = UINT_MAX,
+bool StrictlyUnsigned = false) {
   llvm::APSInt I(32);
   if (Expr->isTypeDependent() || Expr->isValueDependent() ||
   !Expr->isIntegerConstantExpr(I, S.Context)) {
@@ -249,6 +253,11 @@
 return false;
   }
 
+  if (StrictlyUnsigned && I.isSigned() && I.isNegative()) {
+S.Diag(getAttrLoc(AI), diag::err_attribute_argument_negative) << AI;
+return false;
+  }
+
   

[PATCH] D51544: [OpenCL] Split opencl-c.h header

2018-09-05 Thread Andrew Savonichev via Phabricator via cfe-commits
asavonic added a comment.

In https://reviews.llvm.org/D51544#1224730, @Anastasia wrote:

> It seems generally good to partition this big header but I am trying to 
> understand what problem is it trying to solve now?


Main motivation is to reduce memory footprint by factoring out everything that 
is 'common' between PCHs compiled for different targets (CL1.2/2.0 and 
spir/spir64).

> So if we want to add these 2 devices, we now need 4*2 different PCHs,
>  since every combination of -cl-std and -triple must be compiled twice
>  with different OpenCL extensions defines.
> 
> Size of each PCH is 2.5M, so we need ~20M of memory to store our
>  PCHs. If we want to add more devices or support another OpenCL C
>  version, the size will double.

This also allows to do 'partial' pre-compilation, where 'common' part is 
pre-compiled into a single target independent PCH, and plain header is used for 
all target-specific things.
In this case, you no longer need to maintain different target-specific PCHs and 
this greatly simplifies the whole process.

> opencl-c-platform.h (5K LOC) must still be pre-compiled for each
>  supported combination, but since it is a lot smaller (~0.5M vs
>  original 2.5M), it is not that bad. Or we can sacrifice some
>  performance and leave this header without pre-compilation: large
>  portion of opencl-c-platform.h contains vendor extensions, so it will
>  be removed by preprocessor anyway.


Repository:
  rC Clang

https://reviews.llvm.org/D51544



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


[PATCH] D51544: [OpenCL] Split opencl-c.h header

2018-08-31 Thread Andrew Savonichev via Phabricator via cfe-commits
asavonic created this revision.
asavonic added reviewers: Anastasia, yaxunl, bader.
Herald added subscribers: cfe-commits, jfb, mgorny.

TL;DR
-

This patch splits huge opencl-c.h header into multiple headers to
support efficient use of Precompiled Headers (or Modules):

- opencl-c-defs.h contains all preprocessor macros. Macros are not saved in 
PCHs.
- opencl-c-common.h contains builtins which do not depend on any preprocessor 
macro (extensions, OpenCL C version).
- opencl-c-fp16.h and opencl-c-fp64.h contain builtins which require either 
cl_khr_fp16 or cl_khr_fp64 macros, but they do not depend on other extensions 
and OpenCL C version.
- opencl-c-platform.h (looking for a better name! 'target' maybe?) contains all 
other builtins which have more complicated requirements.

Umbrella header opencl-c.h includes all headers above, so this change
is backward compatible with the original design.

Details
---

Typical OpenCL compiler implicitly includes opencl-c.h before
compiling user code:

  #include "opencl-c.h"
  __kernel void k() { printf("hello world\n"); }

With this approach, even for tiny programs compiler spends most of its
time on parsing of opencl-c.h header (which has more than 16000 LOC),
so it takes ~1s to compile our hello world example into LLVM IR.

Obvious solution for this problem is to compile opencl-c.h into an AST
only once, and then use this AST to compile user code. This feature
can be implemented using Precompiled Headers or Clang Modules, but it
has one major drawback: AST must be built with the same set of
preprocessor macros and the same target triple as the the user
code. Consider the following example:

opencl-c.h:

  #if __OPENCL_C_VERSION__ >= CL_VERSION_2_0
float fract(float x, float *iptr);
  #else
float fract(float x, __global float *iptr);
  #endif

If we compile this opencl-c.h into an AST, only one of these two
functions will be present. We cannot use this AST to compile for both
OpenCL C 1.2 and 2.0.

Another example: if we compile opencl-c.h into an AST with
spir-unknown-unknown (32bit) target triple, AST will have 'int'
instead of 'size_t':

opencl-c.h:

  typedef __SIZE_TYPE__ size_t; // __SIZE_TYPE__ is defined to int by clang
  size_t get_global_size(uint dimindx);

This makes the AST non-portable, and it cannot be used to compile for
spir64 triple (where size_t is 64bit integer).

If we want compiler to support CL1.2/CL2.0 for spir/spir64 triple,
we'll need to use 4 different PCHs compiled with different flags:

  -cl-std=CL1.2 + -triple spir
  -cl-std=CL1.2 + -triple spir64
  -cl-std=CL2.0 + -triple spir
  -cl-std=CL2.0 + -triple spir64

Things are getting worse if we want to support multiple devices, which
have different sets of OpenCL extensions. For example, if we want to
support both CPU (which supports cl_khr_fp64) and GPU (which supports
cl_khr_fp16), we must compile opencl-c.h using different options,
because it has the following code all over the place:

  #ifdef cl_khr_fp64
uchar __ovld __cnfn convert_uchar(double);
  #endif
  #ifdef cl_khr_fp16
uchar __ovld __cnfn convert_uchar(half);
  #endif

So if we want to add these 2 devices, we now need 4*2 different PCHs,
since every combination of -cl-std and -triple must be compiled twice
with different OpenCL extensions defines.

Size of each PCH is 2.5M, so we need ~20M of memory to store our
PCHs. If we want to add more devices or support another OpenCL C
version, the size will double.

For a C/C++ compiler this is not a problem: clang maintains a cache so
that only combinations which are actually used are saved to a
disk. OpenCL compilers are different, because they are often
distributed as a shared library. Being a library, it is not expected
to write something on a disk, because it rises a number of questions,
such as: "where do we have a writable temporary directory?" and "how
much space we can consume for PCHs?". For some targets (say, embedded
devices) it is better to avoid this approach.

To solve this problem, the patch splits opencl-c.h header into
multiple headers.

First, we split out 'common' functions, which should be present
regardless of OpenCL C version or extensions. All builtins which have
'core' types, such as convert, math and simple image builtins are
moved into opencl-c-common.h (8K LOC).

Second, split out all functions which are 'common' between OpenCL
version, but require either cl_khr_fp16 or cl_khr_fp64 (not both at
the same time!). Two headers (opencl-c-fp16.h and opencl-c-fp64.h)
have 2K LOC each.

Everything else goes into opencl-c-platform.h (5K LOC).

All macros go in opencl-c-defs.h, because macros cannot be
pre-compiled into AST.

With this setup, we can compile opencl-c-common.h, opencl-c-fp16.h and
opencl-c-fp64.h into PCHs with one set of extensions/OpenCL version,
and use them for any other set of extensions/OpenCL version. Clang
will detect this and throw out an error, which can be safely disabled
by -fno-validate-pch option.


[PATCH] D50259: [OpenCL] Disallow negative attribute arguments

2018-08-03 Thread Andrew Savonichev via Phabricator via cfe-commits
asavonic created this revision.
asavonic added reviewers: Anastasia, yaxunl.
Herald added a subscriber: cfe-commits.

Negative arguments in kernel attributes are silently bitcast'ed to
unsigned, for example:

  __attribute__((reqd_work_group_size(1, -1, 1)))
  __kernel void k() {}

is a complete equivalent of:

  __attribute__((reqd_work_group_size(1, 4294967294, 1)))
  __kernel void k() {}

This is likely an error, so the patch forbids negative arguments in
several OpenCL attributes. Users who really want 4294967294 can still
use it as an unsigned representation.

Change-Id: I910b5c077f5f29e02a1572d9202f0fdbea5280fd


Repository:
  rC Clang

https://reviews.llvm.org/D50259

Files:
  include/clang/Basic/DiagnosticSemaKinds.td
  lib/Sema/SemaDeclAttr.cpp
  test/SemaOpenCL/invalid-kernel-attrs.cl


Index: test/SemaOpenCL/invalid-kernel-attrs.cl
===
--- test/SemaOpenCL/invalid-kernel-attrs.cl
+++ test/SemaOpenCL/invalid-kernel-attrs.cl
@@ -37,3 +37,10 @@
 __attribute__((intel_reqd_sub_group_size(8))) void kernel14(){} // 
expected-error {{attribute 'intel_reqd_sub_group_size' can only be applied to 
an OpenCL kernel}}
 kernel __attribute__((intel_reqd_sub_group_size(0))) void kernel15(){} // 
expected-error {{'intel_reqd_sub_group_size' attribute must be greater than 0}}
 kernel __attribute__((intel_reqd_sub_group_size(8))) 
__attribute__((intel_reqd_sub_group_size(16))) void kernel16() {}  
//expected-warning{{attribute 'intel_reqd_sub_group_size' is already applied 
with different parameters}}
+
+__kernel __attribute__((work_group_size_hint(8,-16,32))) void neg1() {} 
//expected-error{{negative argument is not allowed for 'work_group_size_hint' 
attribute}}
+__kernel __attribute__((reqd_work_group_size(8,16,-32))) void neg2(){} // 
expected-error{{negative argument is not allowed for 'reqd_work_group_size' 
attribute}}
+
+// 4294967294 is a negative integer if treated as signed.
+// Should compile successfully, since we expect an unsigned.
+__kernel __attribute__((reqd_work_group_size(8,16,4294967294))) void ok1(){}
Index: lib/Sema/SemaDeclAttr.cpp
===
--- lib/Sema/SemaDeclAttr.cpp
+++ lib/Sema/SemaDeclAttr.cpp
@@ -239,9 +239,13 @@
 
 /// If Expr is a valid integer constant, get the value of the integer
 /// expression and return success or failure. May output an error.
+///
+/// Negative argument is implicitly converted to unsigned, unless
+/// \p StrictlyUnsigned is true.
 template 
 static bool checkUInt32Argument(Sema , const AttrInfo , const Expr *Expr,
-uint32_t , unsigned Idx = UINT_MAX) {
+uint32_t , unsigned Idx = UINT_MAX,
+bool StrictlyUnsigned = false) {
   llvm::APSInt I(32);
   if (Expr->isTypeDependent() || Expr->isValueDependent() ||
   !Expr->isIntegerConstantExpr(I, S.Context)) {
@@ -262,6 +266,12 @@
 return false;
   }
 
+  if (StrictlyUnsigned && I.isSigned() && I.isNegative()) {
+S.Diag(getAttrLoc(AI), diag::err_attribute_argument_negative)
+<< getAttrName(AI);
+return false;
+  }
+
   Val = (uint32_t)I.getZExtValue();
   return true;
 }
@@ -2793,7 +2803,8 @@
   uint32_t WGSize[3];
   for (unsigned i = 0; i < 3; ++i) {
 const Expr *E = AL.getArgAsExpr(i);
-if (!checkUInt32Argument(S, AL, E, WGSize[i], i))
+if (!checkUInt32Argument(S, AL, E, WGSize[i], i,
+ /*StrictlyUnsigned=*/true))
   return;
 if (WGSize[i] == 0) {
   S.Diag(AL.getLoc(), diag::err_attribute_argument_is_zero)
Index: include/clang/Basic/DiagnosticSemaKinds.td
===
--- include/clang/Basic/DiagnosticSemaKinds.td
+++ include/clang/Basic/DiagnosticSemaKinds.td
@@ -2512,6 +2512,8 @@
   "constant|a string|an identifier}1">;
 def err_attribute_argument_outof_range : Error<
   "%0 attribute requires integer constant between %1 and %2 inclusive">;
+def err_attribute_argument_negative : Error<
+  "negative argument is not allowed for %0 attribute">;
 def err_init_priority_object_attr : Error<
   "can only use 'init_priority' attribute on file-scope definitions "
   "of objects of class type">;


Index: test/SemaOpenCL/invalid-kernel-attrs.cl
===
--- test/SemaOpenCL/invalid-kernel-attrs.cl
+++ test/SemaOpenCL/invalid-kernel-attrs.cl
@@ -37,3 +37,10 @@
 __attribute__((intel_reqd_sub_group_size(8))) void kernel14(){} // expected-error {{attribute 'intel_reqd_sub_group_size' can only be applied to an OpenCL kernel}}
 kernel __attribute__((intel_reqd_sub_group_size(0))) void kernel15(){} // expected-error {{'intel_reqd_sub_group_size' attribute must be greater than 0}}
 kernel __attribute__((intel_reqd_sub_group_size(8))) __attribute__((intel_reqd_sub_group_size(16))) void kernel16() {}  

[PATCH] D49723: [OpenCL] Check for invalid kernel arguments in array types

2018-07-27 Thread Andrew Savonichev via Phabricator via cfe-commits
asavonic updated this revision to Diff 157688.
asavonic added a comment.

Rollback accidentally squashed commit.


Repository:
  rC Clang

https://reviews.llvm.org/D49723

Files:
  lib/Sema/SemaDecl.cpp
  test/SemaOpenCL/invalid-kernel-parameters.cl


Index: test/SemaOpenCL/invalid-kernel-parameters.cl
===
--- test/SemaOpenCL/invalid-kernel-parameters.cl
+++ test/SemaOpenCL/invalid-kernel-parameters.cl
@@ -136,3 +136,16 @@
 };
 
 kernel void pointer_in_nested_struct_arg_2(struct Valid valid, struct 
NestedPointer arg, struct AlsoUser also) { } // expected-error 2 {{struct 
kernel parameters may not contain pointers}}
+
+struct ArrayOfPtr // expected-note{{within field of type 'ArrayOfPtr' declared 
here}}
+{
+  float *arr[3]; // expected-note{{field of illegal type 'float *[3]' declared 
here}}
+ // expected-note@-1{{field of illegal type 'float *[3]' 
declared here}}
+};
+kernel void array_of_ptr(struct ArrayOfPtr arr) {} // expected-error{{struct 
kernel parameters may not contain pointers}}
+
+struct ArrayOfStruct // expected-note{{within field of type 'ArrayOfStruct' 
declared here}}
+{
+  struct ArrayOfPtr arr[3]; // expected-note{{within field of type 'struct 
ArrayOfPtr [3]' declared here}}
+};
+kernel void array_of_struct(struct ArrayOfStruct arr) {} // 
expected-error{{struct kernel parameters may not contain pointers}}
Index: lib/Sema/SemaDecl.cpp
===
--- lib/Sema/SemaDecl.cpp
+++ lib/Sema/SemaDecl.cpp
@@ -8079,6 +8079,15 @@
   if (PT->isRecordType())
 return RecordKernelParam;
 
+  // Look into an array argument to check if it has a forbidden type.
+  if (PT->isArrayType()) {
+const Type *UnderlyingTy = PT->getPointeeOrArrayElementType();
+// Call ourself to check an underlying type of an array. Since the
+// getPointeeOrArrayElementType returns an innermost type which is not an
+// array, this recusive call only happens once.
+return getOpenCLKernelParameterType(S, QualType(UnderlyingTy, 0));
+  }
+
   return ValidKernelParam;
 }
 
@@ -8146,9 +8155,14 @@
   SmallVector HistoryStack;
   HistoryStack.push_back(nullptr);
 
-  const RecordDecl *PD = PT->castAs()->getDecl();
-  VisitStack.push_back(PD);
+  // At this point we already handled everything except of a RecordType or
+  // an ArrayType of a RecordType.
+  assert((PT->isArrayType() || PT->isRecordType()) && "Unexpected type.");
+  const RecordType *RecTy =
+  PT->getPointeeOrArrayElementType()->getAs();
+  const RecordDecl *OrigRecDecl = RecTy->getDecl();
 
+  VisitStack.push_back(RecTy->getDecl());
   assert(VisitStack.back() && "First decl null?");
 
   do {
@@ -8167,7 +8181,15 @@
 const RecordDecl *RD;
 if (const FieldDecl *Field = dyn_cast(Next)) {
   HistoryStack.push_back(Field);
-  RD = Field->getType()->castAs()->getDecl();
+
+  QualType FieldTy = Field->getType();
+  // Other field types (known to be valid or invalid) are handled while we
+  // walk around RecordDecl::fields().
+  assert((FieldTy->isArrayType() || FieldTy->isRecordType()) &&
+ "Unexpected type.");
+  const Type *FieldRecTy = FieldTy->getPointeeOrArrayElementType();
+
+  RD = FieldRecTy->castAs()->getDecl();
 } else {
   RD = cast(Next);
 }
@@ -8204,8 +8226,8 @@
 S.Diag(Param->getLocation(), diag::err_bad_kernel_param_type) << PT;
   }
 
-  S.Diag(PD->getLocation(), diag::note_within_field_of_type)
-<< PD->getDeclName();
+  S.Diag(OrigRecDecl->getLocation(), diag::note_within_field_of_type)
+  << OrigRecDecl->getDeclName();
 
   // We have an error, now let's go back up through history and show where
   // the offending field came from


Index: test/SemaOpenCL/invalid-kernel-parameters.cl
===
--- test/SemaOpenCL/invalid-kernel-parameters.cl
+++ test/SemaOpenCL/invalid-kernel-parameters.cl
@@ -136,3 +136,16 @@
 };
 
 kernel void pointer_in_nested_struct_arg_2(struct Valid valid, struct NestedPointer arg, struct AlsoUser also) { } // expected-error 2 {{struct kernel parameters may not contain pointers}}
+
+struct ArrayOfPtr // expected-note{{within field of type 'ArrayOfPtr' declared here}}
+{
+  float *arr[3]; // expected-note{{field of illegal type 'float *[3]' declared here}}
+ // expected-note@-1{{field of illegal type 'float *[3]' declared here}}
+};
+kernel void array_of_ptr(struct ArrayOfPtr arr) {} // expected-error{{struct kernel parameters may not contain pointers}}
+
+struct ArrayOfStruct // expected-note{{within field of type 'ArrayOfStruct' declared here}}
+{
+  struct ArrayOfPtr arr[3]; // expected-note{{within field of type 'struct ArrayOfPtr [3]' declared here}}
+};
+kernel void array_of_struct(struct ArrayOfStruct arr) {} // expected-error{{struct kernel parameters may not contain pointers}}

  1   2   >