Quuxplusone / LLVMBugzillaTest

0 stars 0 forks source link

FreeBSD 11.0-CURRENT clang++ 3.7.1 gets Bus Errors during compilation on arm that has SCTLR bit[1]==1 (alignment required) #25957

Closed Quuxplusone closed 8 years ago

Quuxplusone commented 8 years ago
Bugzilla Link PR25958
Status RESOLVED FIXED
Importance P normal
Reported by Mark Millard (marklmi26-fbsd@yahoo.com)
Reported on 2015-12-28 14:54:50 -0800
Last modified on 2016-01-05 13:38:24 -0800
Version 3.7
Hardware Other FreeBSD
CC dimitry@andric.com, ditaliano@apple.com, emaste@freebsd.org, james@jamesmolloy.co.uk, jyknight@google.com, llvm-bugs@lists.llvm.org
Fixed by commit(s)
Attachments
Blocks
Blocked by
See also
The program being compiled is all of 11 lines or so:

# more /tmp/main-5dac8d.cpp
# 1 "<built-in>"
# 1 "main.cc"
template <class _Tp, class _Up>
struct __has_rebind
{
    template <class _Xp> static char __test(typename _Xp::template rebind<_Up>* = 0);
};

int
main ()
{
return 0;
}

# more /tmp/main-5dac8d.sh
# Crash reproducer for FreeBSD clang version 3.7.1 (tags/RELEASE_371/final
255217) 20151225
# Driver args: "--driver-mode=g++" "main.cc"
# Original command:  "/usr/bin/clang++" "-cc1" "-triple" "armv6k--freebsd11.0-
gnueabi" "-emit-obj" "-mrelax-all" "-disable-free" "-main-file-name" "main.cc"
"-mrelocation-model" "static" "-mthread-model" "posix" "-mdisable-fp-elim" "-
masm-verbose" "-mconstructor-aliases" "-target-cpu" "arm1176jzf-s" "-target-
feature" "+soft-float" "-target-feature" "+soft-float-abi" "-target-feature" "-
neon" "-target-feature" "-crypto" "-target-abi" "aapcs-linux" "-msoft-float" "-
mfloat-abi" "soft" "-dwarf-column-info" "-resource-dir"
"/usr/bin/../lib/clang/3.7.1" "-internal-isystem" "/usr/include/c++/v1" "-
fdeprecated-macro" "-fdebug-compilation-dir" "/root/c_tests" "-ferror-limit"
"19" "-fmessage-length" "338" "-mstackrealign" "-fno-signed-char" "-fobjc-
runtime=gnustep" "-fcxx-exceptions" "-fexceptions" "-fdiagnostics-show-option"
"-fcolor-diagnostics" "-o" "/tmp/main-e20b38.o" "-x" "c++" "main.cc"
 "/usr/bin/clang++" "-cc1" "-triple" "armv6k--freebsd11.0-gnueabi" "-emit-obj" "-mrelax-all" "-disable-free" "-main-file-name" "main.cc" "-mrelocation-model" "static" "-mthread-model" "posix" "-mdisable-fp-elim" "-masm-verbose" "-mconstructor-aliases" "-target-cpu" "arm1176jzf-s" "-target-feature" "+soft-float" "-target-feature" "+soft-float-abi" "-target-feature" "-neon" "-target-feature" "-crypto" "-target-abi" "aapcs-linux" "-msoft-float" "-mfloat-abi" "soft" "-dwarf-column-info" "-fdeprecated-macro" "-ferror-limit" "19" "-fmessage-length" "338" "-mstackrealign" "-fno-signed-char" "-fobjc-runtime=gnustep" "-fcxx-exceptions" "-fexceptions" "-fdiagnostics-show-option" "-fcolor-diagnostics" "-x" "c++" "main-5dac8d.cpp"

The code involved is from lib/AST/Type.cpp :

DependentTemplateSpecializationType::DependentTemplateSpecializationType(
                        ElaboratedTypeKeyword Keyword,
                        NestedNameSpecifier *NNS, const IdentifierInfo *Name,
                        unsigned NumArgs, const TemplateArgument *Args,
                        QualType Canon)
 : TypeWithKeyword(Keyword, DependentTemplateSpecialization, Canon, true, true,
                   /*VariablyModified=*/false,
                   NNS && NNS->containsUnexpandedParameterPack()),
   NNS(NNS), Name(Name), NumArgs(NumArgs) {
 assert((!NNS || NNS->isDependent()) &&
        "DependentTemplateSpecializatonType requires dependent qualifier");
 for (unsigned I = 0; I != NumArgs; ++I) {
   if (Args[I].containsUnexpandedParameterPack())
     setContainsUnexpandedParameterPack();

   new (&getArgBuffer()[I]) TemplateArgument(Args[I]);
 }
}

The failing code is for the "placement new" in the loop:

A) &getArgBuffer()[I] is not always an address for which the vst1.64
instruction gets an aligned address.

but. . .

B) TemplateArgument(Args[I])'s copy construction activity has code (such as the
vst1.64) requiring a specific alignment when SCTLR bit[1]==1.

C) Nothing here has any explicitly packed data structures.

As for (A):

class DependentTemplateSpecializationType :
 public TypeWithKeyword, public llvm::FoldingSetNode {
. . .
 const TemplateArgument *getArgBuffer() const {
   return reinterpret_cast<const TemplateArgument*>(this+1);
 }
 TemplateArgument *getArgBuffer() {
   return reinterpret_cast<TemplateArgument*>(this+1);
 }

clang++ is over-allocating the space for the
DependentTemplateSpecializationType objects and using the extra space that is
afterwards to hold (a somewhat C-style array of) TemplateArgument instances.
But the logic for this does nothing explicit about alignment of the
TemplateArgument instance pointers, not even partially via explicitly
controlling sizeof(DependentTemplateSpecializationType).

sizeof(TemplateArgument) also needs to be controlled in order to have the
notation &getArgBuffer()[I] maintain alignment in its results when
&getArgBuffer()[0] is well aligned.

The existing code does not explicitly force any specific minimum
TemplateArgument alignment, other than 1. (Implicit ABI rules might get some
alignment --if some of those rules are being applied.

Separately there is the issue that the code produced did not treat the pointers
returned from getArgBuffer() methods as "opaque pointer" examples but they are.
Having compiled with -fmax-type-align=4 the code should have not have required
8 byte alignment (vst1.64). It should have produced code that required 4 (or 2
or 1). Quoting for -fmax-type-align=?:

Instruct the code generator to not enforce a higher alignment than the given
number (of bytes) when accessing memory via an opaque pointer or reference

Those pointers certainly are opaque and should be treated as such. The
"reinterpret_cast" use is a big clue that clang++ should respect.

In other words: I see two clang++ defects in the overall evidence, one of which
directly leads to the Bus Errors being possible.

backtraces and such follow. . .

Program terminated with signal 10, Bus error.
#0  0x00c404d0 in
clang::DependentTemplateSpecializationType::DependentTemplateSpecializationType
()
[New Thread 22a18000 (LWP 100173/<unknown>)]
(gdb) bt
#0  0x00c404d0 in
clang::DependentTemplateSpecializationType::DependentTemplateSpecializationType
()
#1  0x00d86634 in clang::ASTContext::getDependentTemplateSpecializationType ()
#2  0x00d865d8 in clang::ASTContext::getDependentTemplateSpecializationType ()
#3  0x00d862d4 in clang::ASTContext::getDependentTemplateSpecializationType ()
#4  0x00553b7c in clang::Sema::ActOnTypenameType ()
#5  0x0040cb68 in clang::Parser::TryAnnotateTypeOrScopeToken ()
#6  0x00471198 in $a.28 ()
#7  0x00471198 in $a.28 ()
(gdb) x/1i 0x00c404d0
0xc404d0
<_ZN5clang35DependentTemplateSpecializationTypeC2ENS_21ElaboratedTypeKeywordEPNS_19NestedNameSpecifierEPKNS_14IdentifierInfoEjPKNS_16TemplateArgumentENS_8QualTypeE+356>:
  vst1.64   {d16-d17}, [r4]!
(gdb) info all-registers
r0             0xbfbf9778   -1077962888
r1             0x22ac59c4   581720516
r2             0xc45ff8 12869624
r3             0x2  2
r4             0x22ac59ac   581720492
. . .
Quuxplusone commented 8 years ago

This llvm.org submittal is basically a duplicate of what I submitted to FreeBSD's bugzilla:

https://bugs.freebsd.org/bugzilla/show_bug.cgi?id=205663

Quuxplusone commented 8 years ago

Hi Mark,

Thanks for raising this. Before checking the specifics of what you found - did you compile Clang with -mno-unaligned-access? We will by default compile assuming SCTLR.A is 0. -mno-unaligned-access switches this assumption off and enables strict alignment mode.

Cheers,

James

Quuxplusone commented 8 years ago
I've built clang++ for an rpi2 many ways. All crash in the SCTLR bit[1]==1
context on arm. FreeBSD 11.0-CURRENT (including clang) at was in sue for the
report was cross built from amd64 FreeBSD with:

-target armv6--freebsd11.0-gnueabi
-march=armv7a
-fmax-type-align=4
-mno-unaligned-access
-target armv6-gnueabi-freebsd11.0

(Yea, two "-targets" ended up being involved in that order --via the build
system adding one to mine.)

That is per the below extraction from the script log of the build showing the
specific clang++ source code file that has the source code that I reported:

--- Type.o ---
/usr/bin/clang++ -target armv6--freebsd11.0-gnueabi -march=armv7a -fmax-type-
align=4 -mno-unaligned-access -target armv6-gnueabi-freebsd11.0 --
sysroot=/usr/obj/clang/arm.armv6/usr/src/tmp -B/usr/local
/arm-gnueabi-freebsd/bin/ --sysroot=/usr/obj/clang/arm.armv6/usr/src/tmp -
B/usr/local/arm-gnueabi-freebsd/bin/  -O -pipe -mfloat-abi=softfp -
I/usr/src/lib/clang/libclangast/../../../contrib/llvm/inclu
de -I/usr/src/lib/clang/libclangast/../../../contrib/llvm/tools/clang/include -
I/usr/src/lib/clang/libclangast/../../../contrib/llvm/tools/clang/lib/AST -I. -
I/usr/src/lib/clang/libclangast/../../../c
ontrib/llvm/../../lib/clang/include -DLLVM_ON_UNIX -DLLVM_ON_FREEBSD -
D__STDC_LIMIT_MACROS -D__STDC_CONSTANT_MACROS -DCLANG_ENABLE_ARCMT -
DCLANG_ENABLE_STATIC_ANALYZER -fno-strict-aliasing -DLLVM_DEFA
ULT_TARGET_TRIPLE=\"armv6-gnueabi-freebsd11.0\" -DLLVM_HOST_TRIPLE=\"armv6-
unknown-freebsd11.0\" -DDEFAULT_SYSROOT=\"\" -MD -MP -MF.depend.Type.o -
MTType.o -Qunused-arguments  -std=c++11 -fno-exceptio
ns -fno-rtti -stdlib=libc++ -Wno-c++11-extensions -c
/usr/src/lib/clang/libclangast/../../../contrib/llvm/tools/clang/lib/AST/Type.cpp
-o Type.o

Given that clang++ build installed on an rpi2, here is an example using it on
the 11 line example source:

# /usr/bin/clang++ -target armv6--freebsd11.0-gnueabi -march=armv7a -fmax-type-
align=4 -mno-unaligned-access main.cc
clang++: error: unable to execute command: Bus error (core dumped)
clang++: error: clang frontend command failed due to signal (use -v to see
invocation)
FreeBSD clang version 3.7.1 (tags/RELEASE_371/final 255217) 20151225
Target: armv6--freebsd11.0-gnueabi
Thread model: posix
clang++: note: diagnostic msg: PLEASE submit a bug report to
https://bugs.freebsd.org/submit/ and include the crash backtrace, preprocessed
source, and associated run script.
clang++: note: diagnostic msg:
********************

PLEASE ATTACH THE FOLLOWING FILES TO THE BUG REPORT:
Preprocessed source(s) and associated run script(s) are located at:
clang++: note: diagnostic msg: /tmp/main-29523a.cpp
clang++: note: diagnostic msg: /tmp/main-29523a.sh
clang++: note: diagnostic msg:

********************

# more /tmp/main-29523a.sh
# Crash reproducer for FreeBSD clang version 3.7.1 (tags/RELEASE_371/final
255217) 20151225
# Driver args: "--driver-mode=g++" "--target=armv6--freebsd11.0-gnueabi" "-
march=armv7a" "-fmax-type-align=4" "-mno-unaligned-access" "main.cc"
# Original command:  "/usr/bin/clang++" "-cc1" "-triple" "armv7--freebsd11.0-
gnueabi" "-emit-obj" "-mrelax-all" "-disable-free" "-main-file-name" "main.cc"
"-mrelocation-model" "static" "-mthread-model" "posix" "-mdisable-fp-elim" "-
masm-verbose" "-mconstructor-aliases" "-target-cpu" "cortex-a8" "-target-
feature" "+soft-float" "-target-feature" "+soft-float-abi" "-target-feature" "-
neon" "-target-feature" "-crypto" "-target-abi" "aapcs-linux" "-msoft-float" "-
mfloat-abi" "soft" "-backend-option" "-arm-strict-align" "-dwarf-column-info" "-
resource-dir" "/usr/bin/../lib/clang/3.7.1" "-internal-isystem"
"/usr/include/c++/v1" "-fdeprecated-macro" "-fdebug-compilation-dir"
"/root/c_tests" "-ferror-limit" "19" "-fmessage-length" "338" "-mstackrealign"
"-fno-signed-char" "-fobjc-runtime=gnustep" "-fcxx-exceptions" "-fexceptions" "-
fmax-type-align=4" "-fdiagnostics-show-option" "-fcolor-diagnostics" "-o"
"/tmp/main-147b93.o" "-x" "c++" "main.cc"
 "/usr/bin/clang++" "-cc1" "-triple" "armv7--freebsd11.0-gnueabi" "-emit-obj" "-mrelax-all" "-disable-free" "-main-file-name" "main.cc" "-mrelocation-model" "static" "-mthread-model" "posix" "-mdisable-fp-elim" "-masm-verbose" "-mconstructor-aliases" "-target-cpu" "cortex-a8" "-target-feature" "+soft-float" "-target-feature" "+soft-float-abi" "-target-feature" "-neon" "-target-feature" "-crypto" "-target-abi" "aapcs-linux" "-msoft-float" "-mfloat-abi" "soft" "-backend-option" "-arm-strict-align" "-dwarf-column-info" "-fdeprecated-macro" "-ferror-limit" "19" "-fmessage-length" "338" "-mstackrealign" "-fno-signed-char" "-fobjc-runtime=gnustep" "-fcxx-exceptions" "-fexceptions" "-fmax-type-align=4" "-fdiagnostics-show-option" "-fcolor-diagnostics" "-x" "c++" "main-29523a.cpp"

# more /tmp/main-29523a.cpp
# 1 "<built-in>"
# 1 "main.cc"
template <class _Tp, class _Up>
struct __has_rebind
{
    template <class _Xp> static char __test(typename _Xp::template rebind<_Up>* = 0);
};

int
main ()
{
return 0;
}

Anything including <memory> from libc++ hits the problem via such a template
usage.

I'll note that for gcc "-mno-unaligned-access" is described in a way that
packed data structures are mentioned as involved but no data structure is
explicitly marked as packed for the code in question in the clang++ source code
I talked about:

-munaligned-access
-mno-unaligned-access
Enables (or disables) reading and writing of 16- and 32- bit values from
addresses that are not 16- or 32- bit aligned. By default unaligned access is
disabled for all pre-ARMv6 and all ARMv6-M architectures, and enabled for all
other architectures. If unaligned access is not enabled then words in packed
data structures are accessed a byte at a time.

Of course when the code generator is using vst1.64's there can also be 64-bit
(8-Byte) alignment requirements, as it happening in clang++'s internal code for
how it was compiled (see above and the original submittal).
Quuxplusone commented 8 years ago
The following change eliminates the specific Bus Error in clang and allows the
11 line program to compile on an rpi2 --but causes include/clang/AST/Type.h to
pollute a namespace via <cstddef> use:

# svnlite diff /usr/src/contrib/llvm/
Index: /usr/src/contrib/llvm/tools/clang/include/clang/AST/Type.h
===================================================================
--- /usr/src/contrib/llvm/tools/clang/include/clang/AST/Type.h  (revision 292858)
+++ /usr/src/contrib/llvm/tools/clang/include/clang/AST/Type.h  (working copy)
@@ -14,6 +14,8 @@
 #ifndef LLVM_CLANG_AST_TYPE_H
 #define LLVM_CLANG_AST_TYPE_H

+#include <cstddef> // for std::max_align_t
+
 #include "clang/AST/NestedNameSpecifier.h"
 #include "clang/AST/TemplateName.h"
 #include "clang/Basic/AddressSpaces.h"
@@ -4336,7 +4338,7 @@
 /// DependentTemplateSpecializationType - Represents a template
 /// specialization type whose template cannot be resolved, e.g.
 ///   A<T>::template B<T>
-class DependentTemplateSpecializationType :
+class alignas(alignof(std::max_align_t)) DependentTemplateSpecializationType :
   public TypeWithKeyword, public llvm::FoldingSetNode {

   /// \brief The nested name specifier containing the qualifier.

alignof(TemplateArgument) is not used because Types.h is used in contexts where
TemplateArgument is an incomplete type and the notation would be rejected.

The command that built a Type.o that worked was (from the script log of the
build):

--- Type.o ---
/usr/bin/clang++ -target armv6--freebsd11.0-gnueabi -march=armv7a -mno-
unaligned-access -target armv6-gnueabi-freebsd11.0 --
sysroot=/usr/obj/clang/arm.armv6/usr/src/tmp -B/usr/local/arm-gnueabi-freebs
d/bin/ --sysroot=/usr/obj/clang/arm.armv6/usr/src/tmp -B/usr/local/arm-gnueabi-
freebsd/bin/  -O -pipe -mfloat-abi=softfp -
I/usr/src/lib/clang/libclangast/../../../contrib/llvm/include -I/usr/src/lib/c
lang/libclangast/../../../contrib/llvm/tools/clang/include -
I/usr/src/lib/clang/libclangast/../../../contrib/llvm/tools/clang/lib/AST -I. -
I/usr/src/lib/clang/libclangast/../../../contrib/llvm/../../l
ib/clang/include -DLLVM_ON_UNIX -DLLVM_ON_FREEBSD -D__STDC_LIMIT_MACROS -
D__STDC_CONSTANT_MACROS -DCLANG_ENABLE_ARCMT -DCLANG_ENABLE_STATIC_ANALYZER -
fno-strict-aliasing -DLLVM_DEFAULT_TARGET_TRIPLE=\
"armv6-gnueabi-freebsd11.0\" -DLLVM_HOST_TRIPLE=\"armv6-unknown-freebsd11.0\" -
DDEFAULT_SYSROOT=\"\" -MD -MP -MF.depend.Type.o -MTType.o -Qunused-arguments  -
std=c++11 -fno-exceptions -fno-rtti -stdli
b=libc++ -Wno-c++11-extensions -c
/usr/src/lib/clang/libclangast/../../../contrib/llvm/tools/clang/lib/AST/Type.cpp
-o Type.o

So it used (in order):

-target armv6--freebsd11.0-gnueabi
-march=armv7a
-mno-unaligned-access
-target armv6-gnueabi-freebsd11.0

(The first -target is what I supplied, the 2nd is from the FreeBSD build
environment.)

STILL FAILS OVERALL HOWEVER. . .

Unfortunately clang++ on the rpi2 with SCTLR bit[1]==1 dies for other c++
syntax when trying to build part of llvm (early in FreeBSD's buildworld):

Program terminated with signal 10, Bus error.
#0  0x00c43d28 in clang::ASTTemplateArgumentListInfo::initializeFrom ()
[New Thread 22a18000 (LWP 100079/<unknown>)]
(gdb) bt
#0  0x00c43d28 in clang::ASTTemplateArgumentListInfo::initializeFrom ()
#1  0x00c43f10 in clang::ASTTemplateKWAndArgsInfo::initializeFrom ()
#2  0x00cdc788 in
clang::CXXDependentScopeMemberExpr::CXXDependentScopeMemberExpr ()
#3  0x00cdc99c in clang::CXXDependentScopeMemberExpr::Create ()
#4  0x00685384 in clang::Sema::ActOnDependentMemberExpr ()
#5  0x0068abec in clang::Sema::ActOnMemberAccessExpr ()
#6  0x0044a938 in clang::Parser::ParsePostfixExpressionSuffix ()
#7  0x00000000 in ?? ()
(gdb) x/i 0x00c43d28
0xc43d28
<_ZN5clang27ASTTemplateArgumentListInfo14initializeFromERKNS_24TemplateArgumentListInfoERbS4_S4_+396>:  vst1.64 {d16-
d17}, [r0]!
(gdb) info all-regsisters
Undefined info command: "all-regsisters".  Try "help info".
(gdb) info all-registers
r0             0x234b96dc   592156380
. . .

There are lots of places using "this + 1" and reinterpret_cast that therefore
have the potential for a mis-matched alignment between the two types involved,
just like the one I initially reported (some of the below might not be at risk,
I've not inspected all the details of each):

# grep "reinterpret_cast.*this" lib/*/*
lib/AST/Decl.cpp:  SourceLocation *StoredLocs = reinterpret_cast<SourceLocation
*>(this + 1);
lib/AST/Decl.cpp:  *reinterpret_cast<SourceLocation *>(this + 1) = EndLoc;
lib/AST/Decl.cpp:    = reinterpret_cast<const SourceLocation *>(this + 1);
lib/AST/Decl.cpp:                       *reinterpret_cast<const SourceLocation
*>(this + 1));
lib/AST/DeclCXX.cpp:  VarDecl **MyIndices = reinterpret_cast<VarDecl **> (this
+ 1);
lib/AST/DeclOpenMP.cpp:  Expr **Vars = reinterpret_cast<Expr **>(this + 1);
lib/AST/DeclTemplate.cpp:    void **TypesAndInfos = reinterpret_cast<void
**>(this + 1);
lib/AST/DeclTemplate.cpp:    std::memcpy(reinterpret_cast<void*>(this + 1),
Expansions,
lib/AST/Expr.cpp:    return
reinterpret_cast<CXXBaseSpecifier**>(static_cast<Type*>(this)+1);
lib/AST/Expr.cpp:  Stmt *const *SubExprs = reinterpret_cast<Stmt *const *>(this
+ 1);
lib/AST/Expr.cpp:  Stmt *const *SubExprs = reinterpret_cast<Stmt *const *>(this
+ 1);
lib/AST/Expr.cpp:  Stmt *const *SubExprs = reinterpret_cast<Stmt *const *>(this
+ 1);
lib/AST/Expr.cpp:    begin = reinterpret_cast<Stmt **>(this + 1);
lib/AST/ExprCXX.cpp:  Stmt **StoredArgs = reinterpret_cast<Stmt **>(this + 1);
lib/AST/ExprCXX.cpp:
reinterpret_cast<Decl**>(this+1));
lib/AST/Stmt.cpp:  Stmt **Stmts = reinterpret_cast<Stmt **>(this + 1);
lib/AST/Stmt.cpp:      reinterpret_cast<char *>(const_cast<CapturedStmt
*>(this))
lib/AST/Type.cpp:  QualType *argSlot = reinterpret_cast<QualType*>(this+1);
lib/AST/Type.cpp:    = reinterpret_cast<TemplateArgument *>(this + 1);
lib/AST/Type.cpp:    TemplateArgument *Begin =
reinterpret_cast<TemplateArgument *>(this + 1);
lib/Basic/IdentifierTable.cpp:    IdentifierInfo **KeyInfo =
reinterpret_cast<IdentifierInfo **>(this+1);
lib/Basic/IdentifierTable.cpp:    return
reinterpret_cast<keyword_iterator>(this+1);
lib/CodeGen/CGCleanup.h:    return reinterpret_cast<Handler*>(this+1);
lib/CodeGen/CGCleanup.h:    return reinterpret_cast<const Handler*>(this+1);
lib/CodeGen/CGCleanup.h:    return reinterpret_cast<llvm::Value**>(this+1);
lib/CodeGen/CGCleanup.h:    return reinterpret_cast<llvm::Value* const
*>(this+1);
lib/CodeGen/CGExprCXX.cpp:    RValue *getPlacementArgs() { return
reinterpret_cast<RValue*>(this+1); }
lib/CodeGen/CGExprCXX.cpp:      return
reinterpret_cast<DominatingValue<RValue>::saved_type*>(this+1);
lib/Sema/CodeCompleteConsumer.cpp:  Chunk *StoredChunks =
reinterpret_cast<Chunk *>(this + 1);

But there is lots more use of reinterpret_cast where "this" is not involved
that might also have problems. Compare:

# grep -l "reinterpret_cast.*this" lib/*/*
lib/AST/Decl.cpp
lib/AST/DeclCXX.cpp
lib/AST/DeclOpenMP.cpp
lib/AST/DeclTemplate.cpp
lib/AST/Expr.cpp
lib/AST/ExprCXX.cpp
lib/AST/Stmt.cpp
lib/AST/Type.cpp
lib/Basic/IdentifierTable.cpp
lib/CodeGen/CGCleanup.h
lib/CodeGen/CGExprCXX.cpp
lib/Sema/CodeCompleteConsumer.cpp

vs.

# grep -l "reinterpret_cast" lib/*/*
lib/AST/APValue.cpp
lib/AST/ASTDiagnostic.cpp
lib/AST/Decl.cpp
lib/AST/DeclCXX.cpp
lib/AST/DeclOpenMP.cpp
lib/AST/DeclTemplate.cpp
lib/AST/DeclarationName.cpp
lib/AST/Expr.cpp
lib/AST/ExprCXX.cpp
lib/AST/ExprConstant.cpp
lib/AST/ItaniumMangle.cpp
lib/AST/NestedNameSpecifier.cpp
lib/AST/ParentMap.cpp
lib/AST/Stmt.cpp
lib/AST/StmtIterator.cpp
lib/AST/Type.cpp
lib/AST/TypeLoc.cpp
lib/Analysis/CFG.cpp
lib/Basic/Diagnostic.cpp
lib/Basic/FileManager.cpp
lib/Basic/IdentifierTable.cpp
lib/CodeGen/CGBlocks.h
lib/CodeGen/CGCleanup.cpp
lib/CodeGen/CGCleanup.h
lib/CodeGen/CGExpr.cpp
lib/CodeGen/CGExprCXX.cpp
lib/CodeGen/CodeGenModule.cpp
lib/CodeGen/MicrosoftCXXABI.cpp
lib/Driver/MSVCToolChain.cpp
lib/Driver/Tools.h
lib/Format/Encoding.h
lib/Frontend/CacheTokens.cpp
lib/Frontend/DependencyFile.cpp
lib/Frontend/TextDiagnostic.cpp
lib/Lex/HeaderMap.cpp
lib/Lex/LiteralSupport.cpp
lib/Parse/ParseExpr.cpp
lib/Parse/ParseExprCXX.cpp
lib/Parse/ParseObjc.cpp
lib/Parse/ParsePragma.cpp
lib/Parse/ParseTentative.cpp
lib/Parse/Parser.cpp
lib/Rewrite/RewriteRope.cpp
lib/Sema/CodeCompleteConsumer.cpp
lib/Sema/IdentifierResolver.cpp
lib/Sema/SemaCast.cpp
lib/Sema/SemaCodeComplete.cpp
lib/Sema/SemaDecl.cpp
lib/Sema/SemaDeclCXX.cpp
lib/Sema/SemaDeclObjC.cpp
lib/Sema/SemaExprMember.cpp
lib/Sema/SemaExprObjC.cpp
lib/Sema/SemaInit.cpp
lib/Sema/SemaLookup.cpp
lib/Sema/SemaStmt.cpp
lib/Sema/SemaStmtAsm.cpp
lib/Sema/TreeTransform.h
lib/Serialization/ASTReader.cpp
lib/Serialization/ASTReaderDecl.cpp
lib/Serialization/ASTReaderStmt.cpp
lib/Serialization/ASTWriter.cpp
Quuxplusone commented 8 years ago
I've gradually removed more and more Bus Error places by adding
alignas(alignof(std::max_align_t)) to various class/struct declarations. But
now that I'm up to about 76 such additions I think I'm going to give up on
having a personal workaround to enable the clang++ compiler to be used on c++
source code with -march=arm7a with SCTLR bit[1]==1 as the context.

Every single example Bus Error so far is a vst1.64 instruction in clang++
getting a Bus Error for an address that is not aligned appropriately for that
instruction. In every case so far forcing alignment with alignas in the
involved class/struct declarations has allowed the vst1.64 instruction to work.
(No vld1.64 failures have happened so far: the places copied from have been
aligned sufficiently.)

Here are the 76 or so examples (not showing #include <cstddef>'s):

# find -s . -exec grep "alignas.*max_align_t" {} \; | more
class alignas(alignof(std::max_align_t)) StringMapEntry : public
StringMapEntryBase {
class alignas(alignof(std::max_align_t)) RegionNodeBase {
class alignas(alignof(std::max_align_t)) RegionBase : public RegionNodeBase<Tr>
{
class alignas(alignof(std::max_align_t)) FunctionType : public Type {
class alignas(alignof(std::max_align_t)) AttributeSetNode : public
FoldingSetNode {
class alignas(alignof(std::max_align_t)) AttributeSetImpl : public
FoldingSetNode {
class alignas(alignof(std::max_align_t)) MemoryBufferMem : public MemoryBuffer {
class alignas(alignof(std::max_align_t)) MemoryBufferMMapFile : public
MemoryBuffer {
class alignas(alignof(std::max_align_t)) ImportDecl : public Decl {
class alignas(alignof(std::max_align_t)) CXXCtorInitializer {
class alignas(alignof(std::max_align_t)) FriendDecl : public Decl {
class alignas(alignof(std::max_align_t)) ObjCTypeParamList {
class alignas(alignof(std::max_align_t)) OMPThreadPrivateDecl : public Decl {
class alignas(alignof(std::max_align_t)) TemplateParameterList {
class alignas(alignof(std::max_align_t))
DependentFunctionTemplateSpecializationInfo {
class alignas(alignof(std::max_align_t)) NonTypeTemplateParmDecl
class alignas(alignof(std::max_align_t)) TemplateTemplateParmDecl : public
TemplateDecl,
class alignas(alignof(std::max_align_t)) DeclRefExpr : public Expr {
class alignas(alignof(std::max_align_t)) OffsetOfExpr : public Expr {
class alignas(alignof(std::max_align_t)) MemberExpr : public Expr {
class alignas(alignof(std::max_align_t)) CastExpr : public Expr {
class alignas(alignof(std::max_align_t)) DesignatedInitExpr : public Expr {
  class alignas(alignof(std::max_align_t)) Designator {
class alignas(alignof(std::max_align_t)) PseudoObjectExpr : public Expr {
class alignas(alignof(std::max_align_t)) CXXDefaultArgExpr : public Expr {
class alignas(alignof(std::max_align_t)) LambdaExpr : public Expr {
class alignas(alignof(std::max_align_t)) TypeTraitExpr : public Expr {
class alignas(alignof(std::max_align_t)) OverloadExpr : public Expr {
class alignas(alignof(std::max_align_t)) DependentScopeDeclRefExpr : public
Expr {
class alignas(alignof(std::max_align_t)) ExprWithCleanups : public Expr {
class alignas(alignof(std::max_align_t)) CXXUnresolvedConstructExpr : public
Expr {
class alignas(alignof(std::max_align_t)) CXXDependentScopeMemberExpr : public
Expr {
class alignas(alignof(std::max_align_t)) FunctionParmPackExpr : public Expr {
class alignas(alignof(std::max_align_t)) ObjCArrayLiteral : public Expr {
class alignas(alignof(std::max_align_t)) ObjCDictionaryLiteral : public Expr {
class alignas(alignof(std::max_align_t)) ObjCMessageExpr : public Expr {
template <class T> class alignas(alignof(std::max_align_t)) OMPVarListClause :
public OMPClause {
class alignas(alignof(std::max_align_t)) OMPPrivateClause : public
OMPVarListClause<OMPPrivateClause> {
class alignas(alignof(std::max_align_t)) OMPFirstprivateClause : public
OMPVarListClause<OMPFirstprivateClause> {
class alignas(alignof(std::max_align_t)) OMPLastprivateClause : public
OMPVarListClause<OMPLastprivateClause> {
class alignas(alignof(std::max_align_t)) OMPSharedClause : public
OMPVarListClause<OMPSharedClause> {
class alignas(alignof(std::max_align_t)) OMPReductionClause : public
OMPVarListClause<OMPReductionClause> {
class alignas(alignof(std::max_align_t)) OMPLinearClause : public
OMPVarListClause<OMPLinearClause> {
class alignas(alignof(std::max_align_t)) OMPAlignedClause : public
OMPVarListClause<OMPAlignedClause> {
class alignas(alignof(std::max_align_t)) OMPCopyinClause : public
OMPVarListClause<OMPCopyinClause> {
class alignas(alignof(std::max_align_t)) OMPCopyprivateClause : public
OMPVarListClause<OMPCopyprivateClause> {
class alignas(alignof(std::max_align_t)) OMPFlushClause : public
OMPVarListClause<OMPFlushClause> {
class alignas(alignof(std::max_align_t)) OMPDependClause : public
OMPVarListClause<OMPDependClause> {
class alignas(alignof(std::max_align_t)) AttributedStmt : public Stmt {
class alignas(alignof(std::max_align_t)) CapturedStmt : public Stmt {
class alignas(alignof(std::max_align_t)) CXXTryStmt : public Stmt {
class alignas(alignof(std::max_align_t)) ObjCAtTryStmt : public Stmt {
class alignas(alignof(std::max_align_t)) OMPExecutableDirective : public Stmt {
class alignas(alignof(std::max_align_t)) OMPLoopDirective : public
OMPExecutableDirective {
class alignas(alignof(std::max_align_t)) TemplateArgument {
struct alignas(alignof(std::max_align_t)) TemplateArgumentLocInfo {
class alignas(alignof(std::max_align_t)) TemplateArgumentLoc {
struct alignas(alignof(std::max_align_t)) ASTTemplateArgumentListInfo {
class alignas(alignof(std::max_align_t)) UncommonTemplateNameStorage {
class alignas(alignof(std::max_align_t)) OverloadedTemplateStorage : public
UncommonTemplateNameStorage {
class alignas(alignof(std::max_align_t)) FunctionProtoType : public
FunctionType, public llvm::FoldingSetNode {
class alignas(alignof(std::max_align_t)) TemplateSpecializationType
class alignas(alignof(std::max_align_t)) DependentTemplateSpecializationType :
class alignas(alignof(std::max_align_t)) ObjCObjectType : public Type {
class alignas(alignof(std::max_align_t)) CGFunctionInfo : public
llvm::FoldingSetNode {
class alignas(alignof(std::max_align_t)) ModuleMacro : public
llvm::FoldingSetNode {
class alignas(alignof(std::max_align_t)) AttributeList { // TODO: This should
really be called ParsedAttribute
class alignas(alignof(std::max_align_t)) CodeCompletionString {
  class alignas(alignof(std::max_align_t)) ImplicitConversionSequence {
  struct alignas(alignof(std::max_align_t)) TemplateIdAnnotation {
class alignas(alignof(std::max_align_t)) MultiKeywordSelector
class alignas(alignof(std::max_align_t)) EHCatchScope : public EHScope {
class alignas(alignof(std::max_align_t)) EHCleanupScope : public EHScope {
class alignas(alignof(std::max_align_t)) EHFilterScope : public EHScope {
  class alignas(alignof(std::max_align_t)) CallDeleteDuringNew : public EHScopeStack::Cleanup {
  class alignas(alignof(std::max_align_t)) CallDeleteDuringConditionalNew : public EHScopeStack::Cleanup {

A bunch of these deal with aligning this+1 that is then reinterpret_cast. (So
"this" itself ends up being aligned too but the size may have bene adjusted so
that the +1 result is aligned too.)

A few are tied to aligning array entries for when there might be multiple
entries (given that the above sort of thing got the start of the array aligned):

# find . -exec grep "new[ \t]*([^)]*\[" {} \;
        new (&C.Conversions[i]) ImplicitConversionSequence();
    new (&ArgsArray[I]) TemplateArgumentLoc(TArgs[I]);
    new (&ArgBuffer[i]) TemplateArgumentLoc(Info[i]);
    new (&ArgBuffer[i]) TemplateArgumentLoc(Info[i]);
    new (&TemplateArgs[Arg]) TemplateArgument(Args[Arg]);

Without such alignas usage [0] would work from the this+1 handling but [1]
would fail. (When I found an example for one type I tended to find similar code
structure for other types and adjust them at the same time.)

Other examples that I've not gotten around to adjusting may have the array
activity inside a method that is called with the index to use, for example the
TL.setArgLocInfo below Bus Errors (but was inlined):

TypeSourceInfo *
ASTContext::getTemplateSpecializationTypeInfo(TemplateName Name,
                                              SourceLocation NameLoc,
                                        const TemplateArgumentListInfo &Args,
                                              QualType Underlying) const {
  assert(!Name.getAsDependentTemplateName() &&
         "No dependent template names here!");
  QualType TST = getTemplateSpecializationType(Name, Args, Underlying);

  TypeSourceInfo *DI = CreateTypeSourceInfo(TST);
  TemplateSpecializationTypeLoc TL =
      DI->getTypeLoc().castAs<TemplateSpecializationTypeLoc>();
  TL.setTemplateKeywordLoc(SourceLocation());
  TL.setTemplateNameLoc(NameLoc);
  TL.setLAngleLoc(Args.getLAngleLoc());
  TL.setRAngleLoc(Args.getRAngleLoc());
  for (unsigned i = 0, e = TL.getNumArgs(); i != e; ++i)
    TL.setArgLocInfo(i, Args[i].getLocInfo());
  return DI;
}

It appears that much of the reinterpret_cast use in clang++ (and llvm more
generally?) for copying to a new place is suspect and should be validated
relative to alignment requirements, such as for when SCTLR bit[1]==1 for armv7a
contexts.
Quuxplusone commented 8 years ago
Context: RPI2B (cortex-a7) with SCTLR bit[1]==1.

The a.out from compiling the later-below 28 or so non-comment/non-blank line
program gets a Bus Error during the placement-new construction activity. THis
is true for both of the following ways of compiling it (and more):

# clang++ -v -std=c++11 -target armv6--freebsd11.0-gnueabi -march=armv7a -
mcpu=cortex-a7 -mfloat-abi=softfp -mno-unaligned-access main.cc

or via:

# clang++ -v -std=c++11 -target armv6--freebsd11.0-gnueabi -mno-unaligned-
access main.cc

The 28 or so code-line program is designed to use somewhat similar techniques
to some of those used in the clang++/llvm source code base that get Bus Errors
during c++ compiles of source code that uses various parts of C++ notation,
just for a much simpler context.

For an armv7 context the -mfloat-abi=softfp compile enables generation of the
neon vast1.64 style of instruction that gets the error in the clang++ crashes
that I've reported. But that is not required to get the Bus Error. (FreeBSD's
buildworld build environment specifies -mfloat-abi=softfp normally for arm
variants and so with -march=armv7a involved it then implicitly uses neon in the
code generation.)

# more main.cc
// Avoid needing headers that will make the compiler crash on rpi2 with SCTLR
bit[1]==1:
void* operator new(unsigned,void* p) { return p; }

struct t0 {           // The implicit Copy Constructor requires an alignment
    long long  t0_f0; // appropriate to the sizeof/alignof(long long) for SCTLR bit[1]==1.
    char       t0_f1;
} c_t0; // sizeof(t0) is an integral multiple of alignof(long long) so that
array use can work.

struct /* alignas(alignof(struct t0)) */ t1 {
    char       t1_f0; // Unlikely to get default align(t1) being an integral multiple (>=1) of
                      // alignof(long long).

    struct t0* t0_start(void) { return reinterpret_cast<struct t0*>(this+1); }
    // The returned pointer need not be implicitly aligned to the sizeof/alignof(long long)
    // unless the alignas is uncommented.
};

struct t2 {
    struct t1 t2_f0;
    char      t2_f1[2*sizeof(struct t0)]; // t2_f0.t0_start() causes use of this area.
};

struct t0        g[2];
extern struct t0 g[2]; // These and their use prevent optimizing everything
away.

int
main ()
{
    struct t2 t2_v0;

    for (int i=0; i<2; i++)
        new(t2_v0.t2_f0.t0_start()+i)   t0(c_t0); // i==0 gets Bus Error.

    for (int i=0; i<2; i++)
        g[i] = *(t2_v0.t2_f0.t0_start()+i);
    return 0;
}

Uncommenting the alignas for struct t1 avoids the Bus Errors. "struct t0" does
not need alignas. In code where what is analogous to struct t0 is supposed to
be an incomplete type at that point the alignas would need to be independent of
the struct t0 details, more like:

alignas(alignof(std::max_align_t))

(with #include <cstddef> having been used first). This is true in the
llvm/clang code.

The compilation commands with -v outputs that show the differing neon status
are:

# clang++ -v -std=c++11 -target armv6--freebsd11.0-gnueabi -march=armv7a -
mcpu=cortex-a7 -mfloat-abi=softfp -mno-unaligned-access main.cc
FreeBSD clang version 3.7.1 (tags/RELEASE_371/final 255217) 20151225
Target: armv6--freebsd11.0-gnueabi
Thread model: posix
 "/usr/bin/clang++" -cc1 -triple armv7--freebsd11.0-gnueabi -emit-obj -mrelax-all -disable-free -main-file-name main.cc -mrelocation-model static -mthread-model posix -mdisable-fp-elim -masm-verbose -mconstructor-aliases -target-cpu cortex-a7 -target-feature +soft-float-abi -target-abi aapcs-linux -mfloat-abi soft -backend-option -arm-strict-align -v -dwarf-column-info -resource-dir /usr/bin/../lib/clang/3.7.1 -internal-isystem /usr/include/c++/v1 -std=c++11 -fdeprecated-macro -fdebug-compilation-dir /root/c_tests -ferror-limit 19 -fmessage-length 200 -mstackrealign -fno-signed-char -fobjc-runtime=gnustep -fcxx-exceptions -fexceptions -fdiagnostics-show-option -fcolor-diagnostics -o /tmp/main-615940.o -x c++ main.cc
clang -cc1 version 3.7.1 based upon LLVM 3.7.1 default target armv6--
freebsd11.0-gnueabi
#include "..." search starts here:
#include <...> search starts here:
 /usr/include/c++/v1
 /usr/bin/../lib/clang/3.7.1/include
 /usr/include
End of search list.
 "/usr/bin/ld" --eh-frame-hdr -dynamic-linker /libexec/ld-elf.so.1 --hash-style=both --enable-new-dtags -o a.out /usr/lib/crt1.o /usr/lib/crti.o /usr/lib/crtbegin.o -L/usr/lib /tmp/main-615940.o -lc++ -lm -lgcc --as-needed -lgcc_s --no-as-needed -lc -lgcc --as-needed -lgcc_s --no-as-needed /usr/lib/crtend.o /usr/lib/crtn.o

# clang++ -v -std=c++11 -target armv6--freebsd11.0-gnueabi -mno-unaligned-
access main.cc
FreeBSD clang version 3.7.1 (tags/RELEASE_371/final 255217) 20151225
Target: armv6--freebsd11.0-gnueabi
Thread model: posix
 "/usr/bin/clang++" -cc1 -triple armv6k--freebsd11.0-gnueabi -emit-obj -mrelax-all -disable-free -main-file-name main.cc -mrelocation-model static -mthread-model posix -mdisable-fp-elim -masm-verbose -mconstructor-aliases -target-cpu arm1176jzf-s -target-feature +soft-float -target-feature +soft-float-abi -target-feature -neon -target-feature -crypto -target-abi aapcs-linux -msoft-float -mfloat-abi soft -backend-option -arm-strict-align -v -dwarf-column-info -resource-dir /usr/bin/../lib/clang/3.7.1 -internal-isystem /usr/include/c++/v1 -std=c++11 -fdeprecated-macro -fdebug-compilation-dir /root/c_tests -ferror-limit 19 -fmessage-length 200 -mstackrealign -fno-signed-char -fobjc-runtime=gnustep -fcxx-exceptions -fexceptions -fdiagnostics-show-option -fcolor-diagnostics -o /tmp/main-b1e5fb.o -x c++ main.cc
clang -cc1 version 3.7.1 based upon LLVM 3.7.1 default target armv6--
freebsd11.0-gnueabi
#include "..." search starts here:
#include <...> search starts here:
 /usr/include/c++/v1
 /usr/bin/../lib/clang/3.7.1/include
 /usr/include
End of search list.
 "/usr/bin/ld" --eh-frame-hdr -dynamic-linker /libexec/ld-elf.so.1 --hash-style=both --enable-new-dtags -o a.out /usr/lib/crt1.o /usr/lib/crti.o /usr/lib/crtbegin.o -L/usr/lib /tmp/main-b1e5fb.o -lc++ -lm -lgcc --as-needed -lgcc_s --no-as-needed -lc -lgcc --as-needed -lgcc_s --no-as-needed /usr/lib/crtend.o /usr/lib/crtn.o
Quuxplusone commented 8 years ago
FreeBSD folks such as Ian Lepore report things like "I'm using gcc 4.2.1
for arm v4/v5, because clang 3.7 is broken (works to crossbuild, but
fails to run native)." [2015-Dec-24 note in an exchange about an 11.0-CURRENT
svn commit (r291937).]

To get a quick handle on the size of the investigation effort for alignments of
reinterpret_casts to pointer types in llvm/clang I've tried to get
*approximations* of:

A) count of reinterpret_cast's to pointer types that do not involve base types
with "char" or "int8" text (on the same line).

and

B) How many files have such reinterpret_cast's.

# pwd
/usr/src/contrib/llvm

# find -s . -exec grep -E "reinterpret_cast[ \t]*<[^>]*\*" {} \; | grep -v char
| grep -v int8 | wc
     789    3453   51918

# find -s . -exec grep -E "reinterpret_cast[ \t]*<[^>]*(char|int8)[^>]*\*" {}
\; | wc
     171     854   11326

(Some files may have a mix of both with and without char/int8.)

# find -s . -exec grep -E "reinterpret_cast[ \t]*<[^>]*\*" {} \; -print | grep
"^\.\/" | wc
     264     264   10517

# find -s . -exec grep -E "reinterpret_cast[ \t]*<[^>]*(char|int8)[^>]*\*" {}
\; -print | grep "^\.\/" | wc
      71      71    2781

(So 264-71==193 to 264 files.)

And also:

C) How many reinterpret_cast's directly involve the text "this" (on the same
line):

# find -s . -exec grep -E "reinterpret_cast[ \t]*<[^>]*\*.*this" {} \; | grep -
v char | grep -v int8 | wc
     132     739    8443

D) How many files is that?

# find -s . -exec grep -E "reinterpret_cast[ \t]*<[^>]*\*.*this" {} \; -print |
grep "^\.\/" | wc
      47      47    1914
# find -s . -exec grep -E "reinterpret_cast[
\t]*<[^>]*(char|int8)[^>]*\*.*this" {} \; -print | grep "^\.\/" | wc
       5       5     185

(So 47-5==42 to 47 files.)

E) How many reinterpret_cast's do not mention "this", "char", or "int8" (on the
same line):

# find -s . -exec grep -E "reinterpret_cast[ \t]*<[^>]*\*" {} \; | grep -v this
| grep -v char | grep -v int8 | wc
     647    2663   42647

This is the majority of the reinterpret_cast's, by far.

It looks non-trivial to find and adjust the llvm/clang source so that all the
places that do not currently deal with proper alignment for SCTLR bit[1]==1
contexts instead do so.

So it is not likely to be happen time soon, much less finish any time soon.

This will limit FreeBSD 11.0's "self hosting on arm" c++ support via the
system/clang++ tool chain greatly based on the CTLR bit[1]==1 status: cross
builds required from a host not requiring alignment, such as from amd64. (Once
some other C++ tool chain is in place on an arm more native work may then be
possible.)

The C part of clang does appear to compile okay for buildkernel use in the
SCTRL bit[1]==1 context. So far all the misalignments have happened in
compiling-c++ contexts, which is involved for buildworld and for building many
ports.
Quuxplusone commented 8 years ago

Hi Mark,

Thanks for your detailed investigation. I can confirm that this is fixed on trunk and therefore will be fixed for LLVM 3.8.

The fixes were done for SPARC, which requires strict accesses much as ARM does with SCTLR=1.

There was a sequence of commits by James Knight that fixed these, but an example is http://reviews.llvm.org/rL242554 .

The fixes were in a similar vein to yours, but required changes in fewer places and there were a few more sticky issues to solve too. I'll CC James here in case he wants to comment on the current state of the clang codebase for self-hosting in a strict alignment environment.

Cheers,

James

Quuxplusone commented 8 years ago
Thanks for reporting that the issue reported is fixed for 3.8.

Unfortunately for FreeBSD, Ian Lapore now reports:

It's a non-starter for us, because unfortunately they appear to have
removed support for the -arm-use-movt=0 command line option, so now we
can't build ubldr or kernel modules.

-- Ian

I do not know the details in this area but it certainly would be a separate
submittal.
Quuxplusone commented 8 years ago
(In reply to comment #9)
> Thanks for reporting that the issue reported is fixed for 3.8.
>
> Unfortunately for FreeBSD, Ian Lapore now reports:
>
> It's a non-starter for us, because unfortunately they appear to have
> removed support for the -arm-use-movt=0 command line option

This was changed to a subfeature, but I am unsure how to pass a specific
subfeature on the clang command line itself.

In any case the point has become a little moot now, since Davide Italiano has
turned off movt altogether for FreeBSD in r256641:

http://reviews.llvm.org/rL256641

This is because our linker is currently too old to support the necessary
relocation types.