diff -urNp llvm-3.1.src_orig/include/llvm/ADT/Triple.h llvm-3.1.src_hack/include/llvm/ADT/Triple.h
--- llvm-3.1.src_orig/include/llvm/ADT/Triple.h	2012-04-02 14:31:33.000000000 -0400
+++ llvm-3.1.src_hack/include/llvm/ADT/Triple.h	2012-08-23 12:22:27.392322210 -0400
@@ -43,7 +43,7 @@ public:
   enum ArchType {
     UnknownArch,
 
-    arm,     // ARM; arm, armv.*, xscale
+    arm,     // ARM: arm, armv.*, xscale
     cellspu, // CellSPU: spu, cellspu
     hexagon, // Hexagon: hexagon
     mips,    // MIPS: mips, mipsallegrex
@@ -65,7 +65,7 @@ public:
     ptx32,   // PTX: ptx (32-bit)
     ptx64,   // PTX: ptx (64-bit)
     le32,    // le32: generic little-endian 32-bit CPU (PNaCl / Emscripten)
-    amdil   // amdil: amd IL
+    amdil    // amdil: amd IL
   };
   enum VendorType {
     UnknownVendor,
@@ -74,7 +74,8 @@ public:
     PC,
     SCEI,
     BGP,
-    BGQ
+    BGQ,
+    RedHat
   };
   enum OSType {
     UnknownOS,
diff -urNp llvm-3.1.src_orig/lib/Support/Triple.cpp llvm-3.1.src_hack/lib/Support/Triple.cpp
--- llvm-3.1.src_orig/lib/Support/Triple.cpp	2012-04-02 14:31:33.000000000 -0400
+++ llvm-3.1.src_hack/lib/Support/Triple.cpp	2012-08-23 12:22:27.392322210 -0400
@@ -90,6 +90,7 @@ const char *Triple::getVendorTypeName(Ve
   case SCEI: return "scei";
   case BGP: return "bgp";
   case BGQ: return "bgq";
+  case RedHat: return "redhat";
   }
 
   llvm_unreachable("Invalid VendorType!");
diff -urNp llvm-3.1.src_orig/tools/clang/lib/Driver/ToolChains.cpp llvm-3.1.src_hack/tools/clang/lib/Driver/ToolChains.cpp
--- llvm-3.1.src_orig/tools/clang/lib/Driver/ToolChains.cpp	2012-05-11 20:16:02.000000000 -0400
+++ llvm-3.1.src_hack/tools/clang/lib/Driver/ToolChains.cpp	2012-08-24 08:34:04.172308597 -0400
@@ -1185,8 +1185,13 @@ Generic_GCC::GCCInstallationDetector::GC
   static const char *const ARMLibDirs[] = { "/lib" };
   static const char *const ARMTriples[] = {
     "arm-linux-gnueabi",
+    "armv5tel-redhat-linux-gnueabi",
     "arm-linux-androideabi"
   };
+  static const char *const ARMHFTriples[] = {
+    "arm-linux-gnueabihf",
+    "armv7hl-redhat-linux-gnueabi"
+  };
 
   static const char *const X86_64LibDirs[] = { "/lib64", "/lib" };
   static const char *const X86_64Triples[] = {
@@ -1233,12 +1238,23 @@ Generic_GCC::GCCInstallationDetector::GC
   };
 
   switch (TargetTriple.getArch()) {
+
   case llvm::Triple::arm:
   case llvm::Triple::thumb:
+  {
+    StringRef TargetTripleStr = TargetTriple.str();
+
     LibDirs.append(ARMLibDirs, ARMLibDirs + llvm::array_lengthof(ARMLibDirs));
-    TripleAliases.append(
-      ARMTriples, ARMTriples + llvm::array_lengthof(ARMTriples));
+    if ((TargetTriple.getEnvironment() == llvm::Triple::GNUEABIHF) ||
+        (TargetTripleStr.startswith("armv7hl"))) {
+      TripleAliases.append(
+        ARMHFTriples, ARMHFTriples + llvm::array_lengthof(ARMHFTriples));
+    } else {
+      TripleAliases.append(
+        ARMTriples, ARMTriples + llvm::array_lengthof(ARMTriples));
+    }
     break;
+  }
   case llvm::Triple::x86_64:
     LibDirs.append(
       X86_64LibDirs, X86_64LibDirs + llvm::array_lengthof(X86_64LibDirs));
@@ -1362,6 +1378,7 @@ void Generic_GCC::GCCInstallationDetecto
 
       Version = CandidateVersion;
       GCCTriple.setTriple(CandidateTriple);
+
       // FIXME: We hack together the directory name here instead of
       // using LI to ensure stable path separators across Windows and
       // Linux.
@@ -1826,6 +1843,8 @@ enum LinuxDistro {
   Fedora14,
   Fedora15,
   Fedora16,
+  Fedora17,
+  Fedora18,
   FedoraRawhide,
   OpenSuse11_3,
   OpenSuse11_4,
@@ -1885,7 +1904,11 @@ static LinuxDistro DetectLinuxDistro(llv
 
   if (!llvm::MemoryBuffer::getFile("/etc/redhat-release", File)) {
     StringRef Data = File.get()->getBuffer();
-    if (Data.startswith("Fedora release 16"))
+    if (Data.startswith("Fedora release 18"))
+      return Fedora18;
+    else if (Data.startswith("Fedora release 17"))
+      return Fedora17;
+    else if (Data.startswith("Fedora release 16"))
       return Fedora16;
     else if (Data.startswith("Fedora release 15"))
       return Fedora15;
@@ -1957,6 +1980,16 @@ static std::string getMultiarchTriple(co
     // common linux triples that don't quite match the Clang triple for both
     // 32-bit and 64-bit targets. Multiarch fixes its install triples to these
     // regardless of what the actual target triple is.
+  case llvm::Triple::arm:
+  case llvm::Triple::thumb:
+    if (TargetTriple.getEnvironment() == llvm::Triple::GNUEABIHF) {
+      if (llvm::sys::fs::exists(SysRoot + "/lib/arm-linux-gnueabihf"))
+        return "arm-linux-gnueabihf";
+    } else {
+      if (llvm::sys::fs::exists(SysRoot + "/lib/arm-linux-gnueabi"))
+        return "arm-linux-gnueabi";
+    }
+    return TargetTriple.str();
   case llvm::Triple::x86:
     if (llvm::sys::fs::exists(SysRoot + "/lib/i386-linux-gnu"))
       return "i386-linux-gnu";
@@ -2197,6 +2230,9 @@ void Linux::AddClangSystemIncludeArgs(co
   const StringRef ARMMultiarchIncludeDirs[] = {
     "/usr/include/arm-linux-gnueabi"
   };
+  const StringRef ARMHFMultiarchIncludeDirs[] = {
+    "/usr/include/arm-linux-gnueabihf"
+  };
   const StringRef MIPSMultiarchIncludeDirs[] = {
     "/usr/include/mips-linux-gnu"
   };
@@ -2215,7 +2251,10 @@ void Linux::AddClangSystemIncludeArgs(co
   } else if (getTriple().getArch() == llvm::Triple::x86) {
     MultiarchIncludeDirs = X86MultiarchIncludeDirs;
   } else if (getTriple().getArch() == llvm::Triple::arm) {
-    MultiarchIncludeDirs = ARMMultiarchIncludeDirs;
+    if (getTriple().getEnvironment() == llvm::Triple::GNUEABIHF)
+      MultiarchIncludeDirs = ARMHFMultiarchIncludeDirs;
+    else
+      MultiarchIncludeDirs = ARMMultiarchIncludeDirs;
   } else if (getTriple().getArch() == llvm::Triple::mips) {
     MultiarchIncludeDirs = MIPSMultiarchIncludeDirs;
   } else if (getTriple().getArch() == llvm::Triple::mipsel) {
diff -urNp llvm-3.1.src_orig/tools/clang/lib/Driver/Tools.cpp llvm-3.1.src_hack/tools/clang/lib/Driver/Tools.cpp
--- llvm-3.1.src_orig/tools/clang/lib/Driver/Tools.cpp	2012-04-18 17:32:25.000000000 -0400
+++ llvm-3.1.src_hack/tools/clang/lib/Driver/Tools.cpp	2012-08-23 12:22:27.402321428 -0400
@@ -610,18 +610,17 @@ static StringRef getARMFloatABI(const Dr
       break;
     }
 
-    case llvm::Triple::Linux: {
-      if (Triple.getEnvironment() == llvm::Triple::GNUEABI) {
-        FloatABI = "softfp";
-        break;
-      }
-    }
-    // fall through
-
     default:
       switch(Triple.getEnvironment()) {
+      case llvm::Triple::GNUEABIHF:
+        FloatABI = "hard";
+        break;
       case llvm::Triple::GNUEABI:
-        FloatABI = "softfp";
+        // Linux distributions like Fedora set the float ABI in the arch name
+        if (Triple.getArchName().startswith("armv7hl"))
+          FloatABI = "hard";
+        else
+          FloatABI = "softfp";
         break;
       case llvm::Triple::EABI:
         // EABI is always AAPCS, and if it was not marked 'hard', it's softfp
@@ -666,6 +665,7 @@ void Clang::AddARMTargetArgs(const ArgLi
     switch(Triple.getEnvironment()) {
     case llvm::Triple::ANDROIDEABI:
     case llvm::Triple::GNUEABI:
+    case llvm::Triple::GNUEABIHF:
       ABIName = "aapcs-linux";
       break;
     case llvm::Triple::EABI:
