zbrid updated this revision to Diff 192297.
zbrid added a comment.
Herald added a subscriber: jsji.

update whitespace in wasm file to match surrounding


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D59827

Files:
  clang/include/clang/Basic/Builtins.def
  clang/include/clang/Basic/DiagnosticSemaKinds.td
  clang/include/clang/Sema/Sema.h
  clang/lib/CodeGen/CGBuiltin.cpp
  clang/lib/Frontend/InitPreprocessor.cpp
  clang/lib/Sema/SemaChecking.cpp
  clang/test/CodeGen/builtin-speculation-safe-value.c
  clang/test/Preprocessor/init.c
  llvm/include/llvm/CodeGen/ISDOpcodes.h
  llvm/include/llvm/IR/Intrinsics.td
  llvm/include/llvm/IR/IntrinsicsX86.td
  llvm/include/llvm/Target/TargetSelectionDAG.td
  llvm/lib/CodeGen/SelectionDAG/LegalizeIntegerTypes.cpp
  llvm/lib/CodeGen/SelectionDAG/LegalizeTypes.h
  llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp
  llvm/lib/CodeGen/SelectionDAG/SelectionDAGDumper.cpp
  llvm/lib/Target/X86/X86ISelLowering.cpp
  llvm/lib/Target/X86/X86ISelLowering.h
  llvm/lib/Target/X86/X86InstrInfo.td
  llvm/lib/Target/X86/X86SpeculativeLoadHardening.cpp
  llvm/test/CodeGen/X86/speculative-load-hardening-intrinsic.ll

Index: llvm/test/CodeGen/X86/speculative-load-hardening-intrinsic.ll
===================================================================
--- /dev/null
+++ llvm/test/CodeGen/X86/speculative-load-hardening-intrinsic.ll
@@ -0,0 +1,71 @@
+; RUN: llc < %s -mtriple=x86_64-unknown-linux-gnu | FileCheck %s --check-prefix=X64
+
+; ModuleID = 'hello.cpp'
+source_filename = "hello.cpp"
+target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"
+target triple = "x86_64-unknown-linux-gnu"
+
+; Function Attrs: noinline nounwind optnone uwtable
+define dso_local i32 @_Z5foo32i(i32 %a) #0 {
+entry:
+  %a.addr = alloca i32, align 4
+  %b = alloca i32, align 4
+  %b_safe = alloca i32, align 4
+  %c = alloca i32, align 4
+  store i32 %a, i32* %a.addr, align 4
+  %0 = load i32, i32* %a.addr, align 4
+  %mul = mul nsw i32 %0, 100
+  store i32 %mul, i32* %b, align 4
+  %1 = load i32, i32* %b, align 4
+  %2 = call i32 @llvm.speculationsafevalue.i32(i32 %1)
+; X64: movl -12(%rbp), %eax
+; X64: lfence
+; X64: movl %eax, -8(%rbp)
+  store i32 %2, i32* %b_safe, align 4
+  %3 = load i32, i32* %b_safe, align 4
+  %add = add nsw i32 %3, 100
+  store i32 %add, i32* %c, align 4
+  %4 = load i32, i32* %c, align 4
+  ret i32 %4
+}
+
+; Function Attrs: nounwind
+declare i32 @llvm.speculationsafevalue.i32(i32) #1
+
+; Function Attrs: noinline nounwind optnone uwtable
+define dso_local i32 @_Z5foo64i(i32 %a) #0 {
+entry:
+  %a.addr = alloca i32, align 4
+  %b = alloca i64, align 8
+  %b_safe = alloca i64, align 8
+  %c = alloca i64, align 8
+  store i32 %a, i32* %a.addr, align 4
+  %0 = load i32, i32* %a.addr, align 4
+  %mul = mul nsw i32 %0, 100
+  %conv = sext i32 %mul to i64
+  store i64 %conv, i64* %b, align 8
+  %1 = load i64, i64* %b, align 8
+  %2 = call i64 @llvm.speculationsafevalue.i64(i64 %1)
+; X64: movq -32(%rbp), %rax
+; X64: lfence
+; X64: movq %rax, -24(%rbp)
+  store i64 %2, i64* %b_safe, align 8
+  %3 = load i64, i64* %b_safe, align 8
+  %add = add nsw i64 %3, 100
+  store i64 %add, i64* %c, align 8
+  %4 = load i64, i64* %c, align 8
+  %conv1 = trunc i64 %4 to i32
+  ret i32 %conv1
+}
+
+; Function Attrs: nounwind
+declare i64 @llvm.speculationsafevalue.i64(i64) #1
+
+attributes #0 = { noinline nounwind optnone uwtable "correctly-rounded-divide-sqrt-fp-math"="false" "disable-tail-calls"="false" "less-precise-fpmad"="false" "min-legal-vector-width"="0" "no-frame-pointer-elim"="true" "no-frame-pointer-elim-non-leaf" "no-infs-fp-math"="false" "no-jump-tables"="false" "no-nans-fp-math"="false" "no-signed-zeros-fp-math"="false" "no-trapping-math"="false" "stack-protector-buffer-size"="8" "target-cpu"="x86-64" "target-features"="+fxsr,+mmx,+sse,+sse2,+x87" "unsafe-fp-math"="false" "use-soft-float"="false" }
+attributes #1 = { nounwind }
+
+!llvm.module.flags = !{!0}
+!llvm.ident = !{!1}
+
+!0 = !{i32 1, !"wchar_size", i32 4}
+!1 = !{!"clang version 9.0.0 (https://github.com/llvm/llvm-project.git 6fd90b5505fe7cddd0fd798fe9608ea0e0325302)"}
Index: llvm/lib/Target/X86/X86SpeculativeLoadHardening.cpp
===================================================================
--- llvm/lib/Target/X86/X86SpeculativeLoadHardening.cpp
+++ llvm/lib/Target/X86/X86SpeculativeLoadHardening.cpp
@@ -212,6 +212,7 @@
   void hardenIndirectCallOrJumpInstr(
       MachineInstr &MI,
       SmallDenseMap<unsigned, unsigned, 32> &AddrRegToHardenedReg);
+  bool lowerIntrinsic(MachineFunction &MF);
 };
 
 } // end anonymous namespace
@@ -402,16 +403,19 @@
   LLVM_DEBUG(dbgs() << "********** " << getPassName() << " : " << MF.getName()
                     << " **********\n");
 
-  // Only run if this pass is forced enabled or we detect the relevant function
-  // attribute requesting SLH.
-  if (!EnableSpeculativeLoadHardening &&
-      !MF.getFunction().hasFnAttribute(Attribute::SpeculativeLoadHardening))
-    return false;
-
   Subtarget = &MF.getSubtarget<X86Subtarget>();
   MRI = &MF.getRegInfo();
   TII = Subtarget->getInstrInfo();
   TRI = Subtarget->getRegisterInfo();
+  bool Modified = lowerIntrinsic(MF);
+
+  // Only run this pass completely if it is forced enabled or if we detect the relevant function
+  // attribute requesting SLH. Otherwise we should only check for intrinsics that we must lower by adding an lfence.
+  if (!EnableSpeculativeLoadHardening &&
+      !MF.getFunction().hasFnAttribute(Attribute::SpeculativeLoadHardening)) {
+
+    return false || Modified;
+  }
 
   // FIXME: Support for 32-bit.
   PS.emplace(MF, &X86::GR64_NOSPRegClass);
@@ -597,6 +601,37 @@
   }
 }
 
+bool X86SpeculativeLoadHardeningPass::lowerIntrinsic(
+    MachineFunction &MF) {
+  bool Modified = false;
+  for (MachineBasicBlock &MBB : MF) {
+    MachineBasicBlock::iterator MBBI = MBB.begin();
+    MachineBasicBlock::iterator MBBE = MBB.end();
+    while (MBBI != MBBE) {
+      MachineBasicBlock::iterator NMBBI = std::next(MBBI);
+      MachineInstr &MI = *MBBI;
+      unsigned Opcode = MI.getOpcode();
+      if (Opcode == X86::SpeculationSafeValue32) {
+        BuildMI(MBB, NMBBI, DebugLoc(), TII->get(X86::LFENCE));
+        ++NumInstsInserted;
+        ++NumLFENCEsInserted;
+        MRI->replaceRegWith(MI.getOperand(0).getReg(), MI.getOperand(1).getReg());
+        MI.eraseFromParent();
+        Modified = true;
+      } else if (Opcode == X86::SpeculationSafeValue64) {
+        BuildMI(MBB, NMBBI, DebugLoc(), TII->get(X86::LFENCE));
+        ++NumInstsInserted;
+        ++NumLFENCEsInserted;
+        MRI->replaceRegWith(MI.getOperand(0).getReg(), MI.getOperand(1).getReg());
+        MI.eraseFromParent();
+        Modified = true;
+      }
+      MBBI = NMBBI;
+    }
+  }
+  return Modified;
+}
+
 SmallVector<X86SpeculativeLoadHardeningPass::BlockCondInfo, 16>
 X86SpeculativeLoadHardeningPass::collectBlockCondInfo(MachineFunction &MF) {
   SmallVector<BlockCondInfo, 16> Infos;
Index: llvm/lib/Target/X86/X86InstrInfo.td
===================================================================
--- llvm/lib/Target/X86/X86InstrInfo.td
+++ llvm/lib/Target/X86/X86InstrInfo.td
@@ -298,6 +298,9 @@
                                             SDTCisVT<2, i32>, SDTCisVT<3, i32>]>,
                        [SDNPHasChain, SDNPSideEffect]>;
 
+def X86SpeculationSafeValue : SDNode<"X86ISD::SpeculationSafeValue", SDTIntUnaryOp>;
+
+
 //===----------------------------------------------------------------------===//
 // X86 Operand Definitions.
 //
@@ -1164,6 +1167,15 @@
 //  Miscellaneous Instructions.
 //
 
+let hasSideEffects = 1, isCodeGenOnly = 1 in {
+  def SpeculationSafeValue64
+    : PseudoI<(outs GR64:$dst), (ins GR64:$src),
+        [(set GR64:$dst, (X86SpeculationSafeValue GR64:$src))]>;
+  def SpeculationSafeValue32
+    : PseudoI<(outs GR32:$dst), (ins GR32:$src),
+        [(set GR32:$dst, (X86SpeculationSafeValue GR32:$src))]>;
+}
+
 let isBarrier = 1, hasSideEffects = 1, usesCustomInserter = 1,
     SchedRW = [WriteSystem] in
   def Int_eh_sjlj_setup_dispatch
Index: llvm/lib/Target/X86/X86ISelLowering.h
===================================================================
--- llvm/lib/Target/X86/X86ISelLowering.h
+++ llvm/lib/Target/X86/X86ISelLowering.h
@@ -29,6 +29,8 @@
       // Start the numbering where the builtin ops leave off.
       FIRST_NUMBER = ISD::BUILTIN_OP_END,
 
+      SpeculationSafeValue,
+
       /// Bit scan forward.
       BSF,
       /// Bit scan reverse.
@@ -1188,6 +1190,8 @@
       LegalFPImmediates.push_back(Imm);
     }
 
+    SDValue LowerSPECULATION_SAFE_VALUE(SDValue Op, SelectionDAG &DAG) const;
+
     SDValue LowerCallResult(SDValue Chain, SDValue InFlag,
                             CallingConv::ID CallConv, bool isVarArg,
                             const SmallVectorImpl<ISD::InputArg> &Ins,
Index: llvm/lib/Target/X86/X86ISelLowering.cpp
===================================================================
--- llvm/lib/Target/X86/X86ISelLowering.cpp
+++ llvm/lib/Target/X86/X86ISelLowering.cpp
@@ -193,6 +193,9 @@
   setCondCodeAction(ISD::SETUNE, MVT::f64, Expand);
   setCondCodeAction(ISD::SETUNE, MVT::f80, Expand);
 
+  setOperationAction(ISD::SPECULATION_SAFE_VALUE, MVT::i32, Custom);
+  setOperationAction(ISD::SPECULATION_SAFE_VALUE, MVT::i64, Custom);
+
   // Integer absolute.
   if (Subtarget.hasCMov()) {
     setOperationAction(ISD::ABS            , MVT::i16  , Custom);
@@ -4751,6 +4754,14 @@
   }
 }
 
+SDValue X86TargetLowering::LowerSPECULATION_SAFE_VALUE(SDValue Op, SelectionDAG &DAG) const {
+
+  assert((Op.getValueType() == MVT::i64 || Op.getValueType() == MVT::i32) && "Unexpected lowering");
+
+  SDLoc DL(Op);
+  return DAG.getNode(X86ISD::SpeculationSafeValue, DL, Op.getValueType(), Op.getOperand(0));
+}
+
 
 bool X86TargetLowering::getTgtMemIntrinsic(IntrinsicInfo &Info,
                                            const CallInst &I,
@@ -26714,6 +26725,8 @@
   case ISD::GC_TRANSITION_START:
                                 return LowerGC_TRANSITION_START(Op, DAG);
   case ISD::GC_TRANSITION_END:  return LowerGC_TRANSITION_END(Op, DAG);
+  case ISD::SPECULATION_SAFE_VALUE:
+                                return LowerSPECULATION_SAFE_VALUE(Op, DAG);
   }
 }
 
@@ -27913,6 +27926,8 @@
   case X86ISD::NT_BRIND:           return "X86ISD::NT_BRIND";
   case X86ISD::UMWAIT:             return "X86ISD::UMWAIT";
   case X86ISD::TPAUSE:             return "X86ISD::TPAUSE";
+  case X86ISD::SpeculationSafeValue:
+                                   return "X86ISD::SpeculationSafeValue";
   }
   return nullptr;
 }
Index: llvm/lib/CodeGen/SelectionDAG/SelectionDAGDumper.cpp
===================================================================
--- llvm/lib/CodeGen/SelectionDAG/SelectionDAGDumper.cpp
+++ llvm/lib/CodeGen/SelectionDAG/SelectionDAGDumper.cpp
@@ -79,6 +79,7 @@
 #ifndef NDEBUG
   case ISD::DELETED_NODE:               return "<<Deleted Node!>>";
 #endif
+  case ISD::SPECULATION_SAFE_VALUE:     return "SpeculationSafeValue";
   case ISD::PREFETCH:                   return "Prefetch";
   case ISD::ATOMIC_FENCE:               return "AtomicFence";
   case ISD::ATOMIC_CMP_SWAP:            return "AtomicCmpSwap";
Index: llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp
===================================================================
--- llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp
+++ llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp
@@ -6075,6 +6075,12 @@
     setValue(&I, DAG.getNode(ISD::CTPOP, sdl, Ty, Arg));
     return nullptr;
   }
+  case Intrinsic::speculationsafevalue: {
+    SDValue Arg = getValue(I.getArgOperand(0));
+    EVT Ty = Arg.getValueType();
+    setValue(&I, DAG.getNode(ISD::SPECULATION_SAFE_VALUE, sdl, Ty, Arg));
+    return nullptr;
+  }
   case Intrinsic::fshl:
   case Intrinsic::fshr: {
     bool IsFSHL = Intrinsic == Intrinsic::fshl;
Index: llvm/lib/CodeGen/SelectionDAG/LegalizeTypes.h
===================================================================
--- llvm/lib/CodeGen/SelectionDAG/LegalizeTypes.h
+++ llvm/lib/CodeGen/SelectionDAG/LegalizeTypes.h
@@ -343,6 +343,7 @@
   SDValue PromoteIntRes_UNDEF(SDNode *N);
   SDValue PromoteIntRes_VAARG(SDNode *N);
   SDValue PromoteIntRes_XMULO(SDNode *N, unsigned ResNo);
+  SDValue PromoteIntRes_SpeculationSafeValue(SDNode *N);
   SDValue PromoteIntRes_ADDSUBSAT(SDNode *N);
   SDValue PromoteIntRes_MULFIX(SDNode *N);
   SDValue PromoteIntRes_FLT_ROUNDS(SDNode *N);
@@ -438,6 +439,7 @@
   void ExpandIntRes_SADDSUBO          (SDNode *N, SDValue &Lo, SDValue &Hi);
   void ExpandIntRes_UADDSUBO          (SDNode *N, SDValue &Lo, SDValue &Hi);
   void ExpandIntRes_XMULO             (SDNode *N, SDValue &Lo, SDValue &Hi);
+  void ExpandIntRes_SPECULATION_SAFE_VALUE(SDNode *N, SDValue &Lo, SDValue &Hi);
   void ExpandIntRes_ADDSUBSAT         (SDNode *N, SDValue &Lo, SDValue &Hi);
   void ExpandIntRes_MULFIX            (SDNode *N, SDValue &Lo, SDValue &Hi);
 
Index: llvm/lib/CodeGen/SelectionDAG/LegalizeIntegerTypes.cpp
===================================================================
--- llvm/lib/CodeGen/SelectionDAG/LegalizeIntegerTypes.cpp
+++ llvm/lib/CodeGen/SelectionDAG/LegalizeIntegerTypes.cpp
@@ -185,6 +185,9 @@
   case ISD::VECREDUCE_UMIN:
     Res = PromoteIntRes_VECREDUCE(N);
     break;
+  case ISD::SPECULATION_SAFE_VALUE:
+    Res = PromoteIntRes_SpeculationSafeValue(N);
+    break;
   }
 
   // If the result is null then the sub-method took care of registering it.
@@ -787,6 +790,13 @@
                      LHS.getValueType(), LHS, RHS);
 }
 
+SDValue DAGTypeLegalizer::PromoteIntRes_SpeculationSafeValue(SDNode *N) {
+  // Propagate size promotion through the intrinsic.
+  SDValue Op = GetPromotedInteger(N->getOperand(0));
+  return DAG.getNode(N->getOpcode(), SDLoc(N),
+                     Op.getValueType(), Op);
+}
+
 SDValue DAGTypeLegalizer::PromoteIntRes_SExtIntBinOp(SDNode *N) {
   // Sign extend the input.
   SDValue LHS = SExtPromotedInteger(N->getOperand(0));
@@ -1680,6 +1690,9 @@
   case ISD::UMULO:
   case ISD::SMULO: ExpandIntRes_XMULO(N, Lo, Hi); break;
 
+  case ISD::SPECULATION_SAFE_VALUE:
+                   ExpandIntRes_SPECULATION_SAFE_VALUE(N, Lo, Hi); break;
+
   case ISD::SADDSAT:
   case ISD::UADDSAT:
   case ISD::SSUBSAT:
@@ -2399,6 +2412,15 @@
   Hi = DAG.getConstant(0, dl, NVT);
 }
 
+void DAGTypeLegalizer::ExpandIntRes_SPECULATION_SAFE_VALUE(SDNode *N,
+                                                           SDValue &Lo,
+                                                           SDValue &Hi) {
+  SDLoc dl(N);
+  GetExpandedInteger(N->getOperand(0), Lo, Hi);
+  Lo = DAG.getNode(N->getOpcode(), dl, Lo.getValueType(), Lo);
+  Hi = DAG.getNode(N->getOpcode(), dl, Hi.getValueType(), Hi);
+}
+
 void DAGTypeLegalizer::ExpandIntRes_CTTZ(SDNode *N,
                                          SDValue &Lo, SDValue &Hi) {
   SDLoc dl(N);
Index: llvm/include/llvm/Target/TargetSelectionDAG.td
===================================================================
--- llvm/include/llvm/Target/TargetSelectionDAG.td
+++ llvm/include/llvm/Target/TargetSelectionDAG.td
@@ -280,6 +280,10 @@
   SDTCisVT<2, OtherVT>, SDTCisVT<3, OtherVT>, SDTCisPtrTy<4>, SDTCisPtrTy<5>
 ]>;
 
+def SDTSpeculationSafe: SDTypeProfile<1, 1, [
+  SDTCisInt<1>, SDTCisSameAs<1, 0>
+]>;
+
 class SDCallSeqStart<list<SDTypeConstraint> constraints> :
         SDTypeProfile<0, 2, constraints>;
 class SDCallSeqEnd<list<SDTypeConstraint> constraints> :
@@ -581,6 +585,8 @@
 def assertsext : SDNode<"ISD::AssertSext", SDT_assertext>;
 def assertzext : SDNode<"ISD::AssertZext", SDT_assertext>;
 
+def speculationsafevalue : SDNode<"ISD::SPECULATION_SAFE_VALUE",
+                                  SDTSpeculationSafe, []>;
 
 //===----------------------------------------------------------------------===//
 // Selection DAG Condition Codes
Index: llvm/include/llvm/IR/IntrinsicsX86.td
===================================================================
--- llvm/include/llvm/IR/IntrinsicsX86.td
+++ llvm/include/llvm/IR/IntrinsicsX86.td
@@ -4816,3 +4816,7 @@
   def int_x86_invpcid : GCCBuiltin<"__builtin_ia32_invpcid">,
               Intrinsic<[], [llvm_i32_ty, llvm_ptr_ty], []>;
 }
+
+//===----- Intrinsics to mitigate against miss-speculation exploits -------===//
+
+def int_speculationsafevalue : Intrinsic<[llvm_any_ty], [LLVMMatchType<0>], []>;
Index: llvm/include/llvm/IR/Intrinsics.td
===================================================================
--- llvm/include/llvm/IR/Intrinsics.td
+++ llvm/include/llvm/IR/Intrinsics.td
@@ -1168,6 +1168,7 @@
 
 def int_ssa_copy : Intrinsic<[llvm_any_ty], [LLVMMatchType<0>],
                              [IntrNoMem, Returned<0>]>;
+
 //===----------------------------------------------------------------------===//
 // Target-specific intrinsics
 //===----------------------------------------------------------------------===//
Index: llvm/include/llvm/CodeGen/ISDOpcodes.h
===================================================================
--- llvm/include/llvm/CodeGen/ISDOpcodes.h
+++ llvm/include/llvm/CodeGen/ISDOpcodes.h
@@ -881,6 +881,8 @@
     VECREDUCE_AND, VECREDUCE_OR, VECREDUCE_XOR,
     VECREDUCE_SMAX, VECREDUCE_SMIN, VECREDUCE_UMAX, VECREDUCE_UMIN,
 
+    SPECULATION_SAFE_VALUE,
+
     /// BUILTIN_OP_END - This must be the last enum value in this list.
     /// The target-specific pre-isel opcode values start here.
     BUILTIN_OP_END
Index: clang/test/Preprocessor/init.c
===================================================================
--- clang/test/Preprocessor/init.c
+++ clang/test/Preprocessor/init.c
@@ -2845,9 +2845,8 @@
 // I386:#define __i386__ 1
 // I386:#define i386 1
 //
-// RUN: %clang_cc1 -E -dM -ffreestanding -triple=i386-pc-linux-gnu -target-cpu pentium4 < /dev/null | FileCheck -match-full-lines -check-prefix I386-LINUX -check-prefix I386-LINUX-ALIGN32 %s
-// RUN: %clang_cc1 -x c++ -E -dM -ffreestanding -triple=i386-pc-linux-gnu -target-cpu pentium4 < /dev/null | FileCheck -match-full-lines -check-prefix I386-LINUX -check-prefix I386-LINUX-CXX -check-prefix I386-LINUX-ALIGN32 %s
-// RUN: %clang_cc1 -E -dM -ffreestanding -triple=i386-pc-linux-gnu -target-cpu pentium4 -malign-double < /dev/null | FileCheck -match-full-lines -check-prefix I386-LINUX -check-prefix I386-LINUX-ALIGN64 %s
+// RUN: %clang_cc1 -E -dM -ffreestanding -triple=i386-pc-linux-gnu -target-cpu pentium4 < /dev/null | FileCheck -match-full-lines -check-prefix I386-LINUX %s
+// RUN: %clang_cc1 -x c++ -E -dM -ffreestanding -triple=i386-pc-linux-gnu -target-cpu pentium4 < /dev/null | FileCheck -match-full-lines -check-prefix I386-LINUX -check-prefix I386-LINUX-CXX %s
 //
 // I386-LINUX-NOT:#define _LP64
 // I386-LINUX:#define __BIGGEST_ALIGNMENT__ 16
@@ -2884,18 +2883,6 @@
 // I386-LINUX:#define __FLT_MIN_EXP__ (-125)
 // I386-LINUX:#define __FLT_MIN__ 1.17549435e-38F
 // I386-LINUX:#define __FLT_RADIX__ 2
-// I386-LINUX:#define __GCC_ATOMIC_BOOL_LOCK_FREE 2
-// I386-LINUX:#define __GCC_ATOMIC_CHAR16_T_LOCK_FREE 2
-// I386-LINUX:#define __GCC_ATOMIC_CHAR32_T_LOCK_FREE 2
-// I386-LINUX:#define __GCC_ATOMIC_CHAR_LOCK_FREE 2
-// I386-LINUX:#define __GCC_ATOMIC_INT_LOCK_FREE 2
-// I386-LINUX-ALIGN32:#define __GCC_ATOMIC_LLONG_LOCK_FREE 1
-// I386-LINUX-ALIGN64:#define __GCC_ATOMIC_LLONG_LOCK_FREE 2
-// I386-LINUX:#define __GCC_ATOMIC_LONG_LOCK_FREE 2
-// I386-LINUX:#define __GCC_ATOMIC_POINTER_LOCK_FREE 2
-// I386-LINUX:#define __GCC_ATOMIC_SHORT_LOCK_FREE 2
-// I386-LINUX:#define __GCC_ATOMIC_TEST_AND_SET_TRUEVAL 1
-// I386-LINUX:#define __GCC_ATOMIC_WCHAR_T_LOCK_FREE 2
 // I386-LINUX:#define __INT16_C_SUFFIX__
 // I386-LINUX:#define __INT16_FMTd__ "hd"
 // I386-LINUX:#define __INT16_FMTi__ "hi"
@@ -3047,10 +3034,8 @@
 // I386-LINUX:#define __i386__ 1
 // I386-LINUX:#define i386 1
 //
-// RUN: %clang_cc1 -E -dM -ffreestanding -triple=i386-netbsd -target-cpu i486 < /dev/null | FileCheck -match-full-lines -check-prefix I386-NETBSD %s
-// RUN: %clang_cc1 -x c++ -E -dM -ffreestanding -triple=i386-netbsd -target-cpu i486 < /dev/null | FileCheck -match-full-lines -check-prefix I386-NETBSD -check-prefix I386-NETBSD-CXX %s
-// RUN: %clang_cc1 -E -dM -ffreestanding -triple=i386-netbsd -target-cpu i486 -malign-double < /dev/null | FileCheck -match-full-lines -check-prefix I386-NETBSD %s
-//
+// RUN: %clang_cc1 -E -dM -ffreestanding -triple=i386-netbsd < /dev/null | FileCheck -match-full-lines -check-prefix I386-NETBSD %s
+// RUN: %clang_cc1 -x c++ -E -dM -ffreestanding -triple=i386-netbsd < /dev/null | FileCheck -match-full-lines -check-prefix I386-NETBSD -check-prefix I386-NETBSD-CXX %s
 //
 // I386-NETBSD-NOT:#define _LP64
 // I386-NETBSD:#define __BIGGEST_ALIGNMENT__ 16
@@ -3087,17 +3072,6 @@
 // I386-NETBSD:#define __FLT_MIN_EXP__ (-125)
 // I386-NETBSD:#define __FLT_MIN__ 1.17549435e-38F
 // I386-NETBSD:#define __FLT_RADIX__ 2
-// I386-NETBSD:#define __GCC_ATOMIC_BOOL_LOCK_FREE 2
-// I386-NETBSD:#define __GCC_ATOMIC_CHAR16_T_LOCK_FREE 2
-// I386-NETBSD:#define __GCC_ATOMIC_CHAR32_T_LOCK_FREE 2
-// I386-NETBSD:#define __GCC_ATOMIC_CHAR_LOCK_FREE 2
-// I386-NETBSD:#define __GCC_ATOMIC_INT_LOCK_FREE 2
-// I386-NETBSD:#define __GCC_ATOMIC_LLONG_LOCK_FREE 1
-// I386-NETBSD:#define __GCC_ATOMIC_LONG_LOCK_FREE 2
-// I386-NETBSD:#define __GCC_ATOMIC_POINTER_LOCK_FREE 2
-// I386-NETBSD:#define __GCC_ATOMIC_SHORT_LOCK_FREE 2
-// I386-NETBSD:#define __GCC_ATOMIC_TEST_AND_SET_TRUEVAL 1
-// I386-NETBSD:#define __GCC_ATOMIC_WCHAR_T_LOCK_FREE 2
 // I386-NETBSD:#define __INT16_C_SUFFIX__
 // I386-NETBSD:#define __INT16_FMTd__ "hd"
 // I386-NETBSD:#define __INT16_FMTi__ "hi"
@@ -6017,7 +5991,7 @@
 // PPC64LE:#define _ARCH_PWR5 1
 // PPC64LE:#define _ARCH_PWR5X 1
 // PPC64LE:#define _ARCH_PWR6 1
-// PPC64LE-NOT:#define _ARCH_PWR6X 1
+// PPC64LE:#define _ARCH_PWR6X 1
 // PPC64LE:#define _ARCH_PWR7 1
 // PPC64LE:#define _CALL_ELF 2
 // PPC64LE:#define _LITTLE_ENDIAN 1
@@ -6357,7 +6331,7 @@
 // PPCPWR7:#define _ARCH_PWR5 1
 // PPCPWR7:#define _ARCH_PWR5X 1
 // PPCPWR7:#define _ARCH_PWR6 1
-// PPCPWR7-NOT:#define _ARCH_PWR6X 1
+// PPCPWR7:#define _ARCH_PWR6X 1
 // PPCPWR7:#define _ARCH_PWR7 1
 //
 // RUN: %clang_cc1 -E -dM -ffreestanding -triple=powerpc64-none-none -target-cpu power7 -fno-signed-char < /dev/null | FileCheck -match-full-lines -check-prefix PPCPOWER7 %s
@@ -6370,7 +6344,7 @@
 // PPCPOWER7:#define _ARCH_PWR5 1
 // PPCPOWER7:#define _ARCH_PWR5X 1
 // PPCPOWER7:#define _ARCH_PWR6 1
-// PPCPOWER7-NOT:#define _ARCH_PWR6X 1
+// PPCPOWER7:#define _ARCH_PWR6X 1
 // PPCPOWER7:#define _ARCH_PWR7 1
 //
 // RUN: %clang_cc1 -E -dM -ffreestanding -triple=powerpc64-none-none -target-cpu pwr8 -fno-signed-char < /dev/null | FileCheck -match-full-lines -check-prefix PPCPWR8 %s
@@ -6383,7 +6357,7 @@
 // PPCPWR8:#define _ARCH_PWR5 1
 // PPCPWR8:#define _ARCH_PWR5X 1
 // PPCPWR8:#define _ARCH_PWR6 1
-// PPCPWR8-NOT:#define _ARCH_PWR6X 1
+// PPCPWR8:#define _ARCH_PWR6X 1
 // PPCPWR8:#define _ARCH_PWR7 1
 // PPCPWR8:#define _ARCH_PWR8 1
 //
@@ -6400,7 +6374,7 @@
 // PPCPOWER8:#define _ARCH_PWR5 1
 // PPCPOWER8:#define _ARCH_PWR5X 1
 // PPCPOWER8:#define _ARCH_PWR6 1
-// PPCPOWER8-NOT:#define _ARCH_PWR6X 1
+// PPCPOWER8:#define _ARCH_PWR6X 1
 // PPCPOWER8:#define _ARCH_PWR7 1
 // PPCPOWER8:#define _ARCH_PWR8 1
 //
@@ -6414,7 +6388,7 @@
 // PPCPWR9:#define _ARCH_PWR5 1
 // PPCPWR9:#define _ARCH_PWR5X 1
 // PPCPWR9:#define _ARCH_PWR6 1
-// PPCPWR9-NOT:#define _ARCH_PWR6X 1
+// PPCPWR9:#define _ARCH_PWR6X 1
 // PPCPWR9:#define _ARCH_PWR7 1
 // PPCPWR9:#define _ARCH_PWR9 1
 //
@@ -6428,216 +6402,13 @@
 // PPCPOWER9:#define _ARCH_PWR5 1
 // PPCPOWER9:#define _ARCH_PWR5X 1
 // PPCPOWER9:#define _ARCH_PWR6 1
-// PPCPOWER9-NOT:#define _ARCH_PWR6X 1
+// PPCPOWER9:#define _ARCH_PWR6X 1
 // PPCPOWER9:#define _ARCH_PWR7 1
 // PPCPOWER9:#define _ARCH_PWR9 1
 //
 // RUN: %clang_cc1 -E -dM -ffreestanding -triple=powerpc64-none-none -target-feature +float128 -target-cpu power9 -fno-signed-char < /dev/null | FileCheck -check-prefix PPC-FLOAT128 %s
 // PPC-FLOAT128:#define __FLOAT128__ 1
 //
-// RUN: %clang_cc1 -E -dM -ffreestanding -triple=powerpc64-ibm-aix7.1.0.0 -fno-signed-char < /dev/null | FileCheck -match-full-lines -check-prefix PPC64-AIX %s
-//
-// PPC64-AIX:#define _AIX 1
-// PPC64-AIX:#define _ARCH_PPC 1
-// PPC64-AIX:#define _ARCH_PPC64 1
-// PPC64-AIX:#define _BIG_ENDIAN 1
-// PPC64-AIX:#define _IBMR2 1
-// PPC64-AIX-NOT:#define _ILP32 1
-// PPC64-AIX:#define _LONG_LONG 1
-// PPC64-AIX:#define _LP64 1
-// PPC64-AIX:#define _POWER 1
-// PPC64-AIX:#define __64BIT__ 1
-// PPC64-AIX:#define __BIGGEST_ALIGNMENT__ 8
-// PPC64-AIX:#define __BIG_ENDIAN__ 1
-// PPC64-AIX:#define __BYTE_ORDER__ __ORDER_BIG_ENDIAN__
-// PPC64-AIX:#define __CHAR16_TYPE__ unsigned short
-// PPC64-AIX:#define __CHAR32_TYPE__ unsigned int
-// PPC64-AIX:#define __CHAR_BIT__ 8
-// PPC64-AIX:#define __CHAR_UNSIGNED__ 1
-// PPC64-AIX:#define __DBL_DENORM_MIN__ 4.9406564584124654e-324
-// PPC64-AIX:#define __DBL_DIG__ 15
-// PPC64-AIX:#define __DBL_EPSILON__ 2.2204460492503131e-16
-// PPC64-AIX:#define __DBL_HAS_DENORM__ 1
-// PPC64-AIX:#define __DBL_HAS_INFINITY__ 1
-// PPC64-AIX:#define __DBL_HAS_QUIET_NAN__ 1
-// PPC64-AIX:#define __DBL_MANT_DIG__ 53
-// PPC64-AIX:#define __DBL_MAX_10_EXP__ 308
-// PPC64-AIX:#define __DBL_MAX_EXP__ 1024
-// PPC64-AIX:#define __DBL_MAX__ 1.7976931348623157e+308
-// PPC64-AIX:#define __DBL_MIN_10_EXP__ (-307)
-// PPC64-AIX:#define __DBL_MIN_EXP__ (-1021)
-// PPC64-AIX:#define __DBL_MIN__ 2.2250738585072014e-308
-// PPC64-AIX:#define __DECIMAL_DIG__ __LDBL_DECIMAL_DIG__
-// PPC64-AIX:#define __FLT_DENORM_MIN__ 1.40129846e-45F
-// PPC64-AIX:#define __FLT_DIG__ 6
-// PPC64-AIX:#define __FLT_EPSILON__ 1.19209290e-7F
-// PPC64-AIX:#define __FLT_EVAL_METHOD__ 1
-// PPC64-AIX:#define __FLT_HAS_DENORM__ 1
-// PPC64-AIX:#define __FLT_HAS_INFINITY__ 1
-// PPC64-AIX:#define __FLT_HAS_QUIET_NAN__ 1
-// PPC64-AIX:#define __FLT_MANT_DIG__ 24
-// PPC64-AIX:#define __FLT_MAX_10_EXP__ 38
-// PPC64-AIX:#define __FLT_MAX_EXP__ 128
-// PPC64-AIX:#define __FLT_MAX__ 3.40282347e+38F
-// PPC64-AIX:#define __FLT_MIN_10_EXP__ (-37)
-// PPC64-AIX:#define __FLT_MIN_EXP__ (-125)
-// PPC64-AIX:#define __FLT_MIN__ 1.17549435e-38F
-// PPC64-AIX:#define __FLT_RADIX__ 2
-// PPC64-AIX-NOT:#define __ILP32__ 1
-// PPC64-AIX:#define __INT16_C_SUFFIX__
-// PPC64-AIX:#define __INT16_FMTd__ "hd"
-// PPC64-AIX:#define __INT16_FMTi__ "hi"
-// PPC64-AIX:#define __INT16_MAX__ 32767
-// PPC64-AIX:#define __INT16_TYPE__ short
-// PPC64-AIX:#define __INT32_C_SUFFIX__
-// PPC64-AIX:#define __INT32_FMTd__ "d"
-// PPC64-AIX:#define __INT32_FMTi__ "i"
-// PPC64-AIX:#define __INT32_MAX__ 2147483647
-// PPC64-AIX:#define __INT32_TYPE__ int
-// PPC64-AIX:#define __INT64_C_SUFFIX__ L
-// PPC64-AIX:#define __INT64_FMTd__ "ld"
-// PPC64-AIX:#define __INT64_FMTi__ "li"
-// PPC64-AIX:#define __INT64_MAX__ 9223372036854775807L
-// PPC64-AIX:#define __INT64_TYPE__ long int
-// PPC64-AIX:#define __INT8_C_SUFFIX__
-// PPC64-AIX:#define __INT8_FMTd__ "hhd"
-// PPC64-AIX:#define __INT8_FMTi__ "hhi"
-// PPC64-AIX:#define __INT8_MAX__ 127
-// PPC64-AIX:#define __INT8_TYPE__ signed char
-// PPC64-AIX:#define __INTMAX_C_SUFFIX__ L
-// PPC64-AIX:#define __INTMAX_FMTd__ "ld"
-// PPC64-AIX:#define __INTMAX_FMTi__ "li"
-// PPC64-AIX:#define __INTMAX_MAX__ 9223372036854775807L
-// PPC64-AIX:#define __INTMAX_TYPE__ long int
-// PPC64-AIX:#define __INTMAX_WIDTH__ 64
-// PPC64-AIX:#define __INTPTR_FMTd__ "ld"
-// PPC64-AIX:#define __INTPTR_FMTi__ "li"
-// PPC64-AIX:#define __INTPTR_MAX__ 9223372036854775807L
-// PPC64-AIX:#define __INTPTR_TYPE__ long int
-// PPC64-AIX:#define __INTPTR_WIDTH__ 64
-// PPC64-AIX:#define __INT_FAST16_FMTd__ "hd"
-// PPC64-AIX:#define __INT_FAST16_FMTi__ "hi"
-// PPC64-AIX:#define __INT_FAST16_MAX__ 32767
-// PPC64-AIX:#define __INT_FAST16_TYPE__ short
-// PPC64-AIX:#define __INT_FAST32_FMTd__ "d"
-// PPC64-AIX:#define __INT_FAST32_FMTi__ "i"
-// PPC64-AIX:#define __INT_FAST32_MAX__ 2147483647
-// PPC64-AIX:#define __INT_FAST32_TYPE__ int
-// PPC64-AIX:#define __INT_FAST64_FMTd__ "ld"
-// PPC64-AIX:#define __INT_FAST64_FMTi__ "li"
-// PPC64-AIX:#define __INT_FAST64_MAX__ 9223372036854775807L
-// PPC64-AIX:#define __INT_FAST64_TYPE__ long int
-// PPC64-AIX:#define __INT_FAST8_FMTd__ "hhd"
-// PPC64-AIX:#define __INT_FAST8_FMTi__ "hhi"
-// PPC64-AIX:#define __INT_FAST8_MAX__ 127
-// PPC64-AIX:#define __INT_FAST8_TYPE__ signed char
-// PPC64-AIX:#define __INT_LEAST16_FMTd__ "hd"
-// PPC64-AIX:#define __INT_LEAST16_FMTi__ "hi"
-// PPC64-AIX:#define __INT_LEAST16_MAX__ 32767
-// PPC64-AIX:#define __INT_LEAST16_TYPE__ short
-// PPC64-AIX:#define __INT_LEAST32_FMTd__ "d"
-// PPC64-AIX:#define __INT_LEAST32_FMTi__ "i"
-// PPC64-AIX:#define __INT_LEAST32_MAX__ 2147483647
-// PPC64-AIX:#define __INT_LEAST32_TYPE__ int
-// PPC64-AIX:#define __INT_LEAST64_FMTd__ "ld"
-// PPC64-AIX:#define __INT_LEAST64_FMTi__ "li"
-// PPC64-AIX:#define __INT_LEAST64_MAX__ 9223372036854775807L
-// PPC64-AIX:#define __INT_LEAST64_TYPE__ long int
-// PPC64-AIX:#define __INT_LEAST8_FMTd__ "hhd"
-// PPC64-AIX:#define __INT_LEAST8_FMTi__ "hhi"
-// PPC64-AIX:#define __INT_LEAST8_MAX__ 127
-// PPC64-AIX:#define __INT_LEAST8_TYPE__ signed char
-// PPC64-AIX:#define __INT_MAX__ 2147483647
-// PPC64-AIX:#define __LDBL_DECIMAL_DIG__ 17
-// PPC64-AIX:#define __LDBL_DENORM_MIN__ 4.9406564584124654e-324L
-// PPC64-AIX:#define __LDBL_DIG__ 15
-// PPC64-AIX:#define __LDBL_EPSILON__ 2.2204460492503131e-16L
-// PPC64-AIX:#define __LDBL_HAS_DENORM__ 1
-// PPC64-AIX:#define __LDBL_HAS_INFINITY__ 1
-// PPC64-AIX:#define __LDBL_HAS_QUIET_NAN__ 1
-// PPC64-AIX:#define __LDBL_MANT_DIG__ 53
-// PPC64-AIX:#define __LDBL_MAX_10_EXP__ 308
-// PPC64-AIX:#define __LDBL_MAX_EXP__ 1024
-// PPC64-AIX:#define __LDBL_MAX__ 1.7976931348623157e+308L
-// PPC64-AIX:#define __LDBL_MIN_10_EXP__ (-307)
-// PPC64-AIX:#define __LDBL_MIN_EXP__ (-1021)
-// PPC64-AIX:#define __LDBL_MIN__ 2.2250738585072014e-308L
-// PPC64-AIX:#define __LONG_LONG_MAX__ 9223372036854775807LL
-// PPC64-AIX:#define __LONG_MAX__ 9223372036854775807L
-// PPC64-AIX:#define __LP64__ 1
-// PPC64-AIX-NOT:#define __NATURAL_ALIGNMENT__ 1
-// PPC64-AIX:#define __POINTER_WIDTH__ 64
-// PPC64-AIX:#define __POWERPC__ 1
-// PPC64-AIX:#define __PPC64__ 1
-// PPC64-AIX:#define __PPC__ 1
-// PPC64-AIX:#define __PTRDIFF_TYPE__ long int
-// PPC64-AIX:#define __PTRDIFF_WIDTH__ 64
-// PPC64-AIX:#define __REGISTER_PREFIX__
-// PPC64-AIX:#define __SCHAR_MAX__ 127
-// PPC64-AIX:#define __SHRT_MAX__ 32767
-// PPC64-AIX:#define __SIG_ATOMIC_MAX__ 2147483647
-// PPC64-AIX:#define __SIG_ATOMIC_WIDTH__ 32
-// PPC64-AIX:#define __SIZEOF_DOUBLE__ 8
-// PPC64-AIX:#define __SIZEOF_FLOAT__ 4
-// PPC64-AIX:#define __SIZEOF_INT__ 4
-// PPC64-AIX:#define __SIZEOF_LONG_DOUBLE__ 8
-// PPC64-AIX:#define __SIZEOF_LONG_LONG__ 8
-// PPC64-AIX:#define __SIZEOF_LONG__ 8
-// PPC64-AIX:#define __SIZEOF_POINTER__ 8
-// PPC64-AIX:#define __SIZEOF_PTRDIFF_T__ 8
-// PPC64-AIX:#define __SIZEOF_SHORT__ 2
-// PPC64-AIX:#define __SIZEOF_SIZE_T__ 8
-// PPC64-AIX:#define __SIZEOF_WCHAR_T__ 4
-// PPC64-AIX:#define __SIZEOF_WINT_T__ 4
-// PPC64-AIX:#define __SIZE_MAX__ 18446744073709551615UL
-// PPC64-AIX:#define __SIZE_TYPE__ long unsigned int
-// PPC64-AIX:#define __SIZE_WIDTH__ 64
-// PPC64-AIX:#define __UINT16_C_SUFFIX__
-// PPC64-AIX:#define __UINT16_MAX__ 65535
-// PPC64-AIX:#define __UINT16_TYPE__ unsigned short
-// PPC64-AIX:#define __UINT32_C_SUFFIX__ U
-// PPC64-AIX:#define __UINT32_MAX__ 4294967295U
-// PPC64-AIX:#define __UINT32_TYPE__ unsigned int
-// PPC64-AIX:#define __UINT64_C_SUFFIX__ UL
-// PPC64-AIX:#define __UINT64_MAX__ 18446744073709551615UL
-// PPC64-AIX:#define __UINT64_TYPE__ long unsigned int
-// PPC64-AIX:#define __UINT8_C_SUFFIX__
-// PPC64-AIX:#define __UINT8_MAX__ 255
-// PPC64-AIX:#define __UINT8_TYPE__ unsigned char
-// PPC64-AIX:#define __UINTMAX_C_SUFFIX__ UL
-// PPC64-AIX:#define __UINTMAX_MAX__ 18446744073709551615UL
-// PPC64-AIX:#define __UINTMAX_TYPE__ long unsigned int
-// PPC64-AIX:#define __UINTMAX_WIDTH__ 64
-// PPC64-AIX:#define __UINTPTR_MAX__ 18446744073709551615UL
-// PPC64-AIX:#define __UINTPTR_TYPE__ long unsigned int
-// PPC64-AIX:#define __UINTPTR_WIDTH__ 64
-// PPC64-AIX:#define __UINT_FAST16_MAX__ 65535
-// PPC64-AIX:#define __UINT_FAST16_TYPE__ unsigned short
-// PPC64-AIX:#define __UINT_FAST32_MAX__ 4294967295U
-// PPC64-AIX:#define __UINT_FAST32_TYPE__ unsigned int
-// PPC64-AIX:#define __UINT_FAST64_MAX__ 18446744073709551615UL
-// PPC64-AIX:#define __UINT_FAST64_TYPE__ long unsigned int
-// PPC64-AIX:#define __UINT_FAST8_MAX__ 255
-// PPC64-AIX:#define __UINT_FAST8_TYPE__ unsigned char
-// PPC64-AIX:#define __UINT_LEAST16_MAX__ 65535
-// PPC64-AIX:#define __UINT_LEAST16_TYPE__ unsigned short
-// PPC64-AIX:#define __UINT_LEAST32_MAX__ 4294967295U
-// PPC64-AIX:#define __UINT_LEAST32_TYPE__ unsigned int
-// PPC64-AIX:#define __UINT_LEAST64_MAX__ 18446744073709551615UL
-// PPC64-AIX:#define __UINT_LEAST64_TYPE__ long unsigned int
-// PPC64-AIX:#define __UINT_LEAST8_MAX__ 255
-// PPC64-AIX:#define __UINT_LEAST8_TYPE__ unsigned char
-// PPC64-AIX:#define __USER_LABEL_PREFIX__
-// PPC64-AIX:#define __WCHAR_MAX__ 4294967295U
-// PPC64-AIX:#define __WCHAR_TYPE__ unsigned int
-// PPC64-AIX:#define __WCHAR_WIDTH__ 32
-// PPC64-AIX:#define __WINT_TYPE__ int
-// PPC64-AIX:#define __WINT_WIDTH__ 32
-// PPC64-AIX:#define __powerpc64__ 1
-// PPC64-AIX:#define __powerpc__ 1
-// PPC64-AIX:#define __ppc64__ 1
-// PPC64-AIX:#define __ppc__ 1
-//
 // RUN: %clang_cc1 -E -dM -ffreestanding -triple=powerpc64-unknown-linux-gnu -fno-signed-char < /dev/null | FileCheck -match-full-lines -check-prefix PPC64-LINUX %s
 //
 // PPC64-LINUX:#define _ARCH_PPC 1
@@ -7046,218 +6817,6 @@
 // PPC:#define __WINT_WIDTH__ 32
 // PPC:#define __ppc__ 1
 //
-// RUN: %clang_cc1 -E -dM -ffreestanding -triple=powerpc-ibm-aix7.1.0.0 -fno-signed-char < /dev/null | FileCheck -match-full-lines -check-prefix PPC-AIX %s
-//
-// PPC-AIX-NOT:#define __64BIT__ 1
-// PPC-AIX:#define _AIX 1
-// PPC-AIX:#define _ARCH_PPC 1
-// PPC-AIX:#define _BIG_ENDIAN 1
-// PPC-AIX:#define _IBMR2 1
-// PPC-AIX:#define _LONG_LONG 1
-// PPC-AIX-NOT:#define _LP64 1
-// PPC-AIX:#define _POWER 1
-// PPC-AIX:#define __BIGGEST_ALIGNMENT__ 8
-// PPC-AIX:#define __BIG_ENDIAN__ 1
-// PPC-AIX:#define __BYTE_ORDER__ __ORDER_BIG_ENDIAN__
-// PPC-AIX:#define __CHAR16_TYPE__ unsigned short
-// PPC-AIX:#define __CHAR32_TYPE__ unsigned int
-// PPC-AIX:#define __CHAR_BIT__ 8
-// PPC-AIX:#define __CHAR_UNSIGNED__ 1
-// PPC-AIX:#define __DBL_DENORM_MIN__ 4.9406564584124654e-324
-// PPC-AIX:#define __DBL_DIG__ 15
-// PPC-AIX:#define __DBL_EPSILON__ 2.2204460492503131e-16
-// PPC-AIX:#define __DBL_HAS_DENORM__ 1
-// PPC-AIX:#define __DBL_HAS_INFINITY__ 1
-// PPC-AIX:#define __DBL_HAS_QUIET_NAN__ 1
-// PPC-AIX:#define __DBL_MANT_DIG__ 53
-// PPC-AIX:#define __DBL_MAX_10_EXP__ 308
-// PPC-AIX:#define __DBL_MAX_EXP__ 1024
-// PPC-AIX:#define __DBL_MAX__ 1.7976931348623157e+308
-// PPC-AIX:#define __DBL_MIN_10_EXP__ (-307)
-// PPC-AIX:#define __DBL_MIN_EXP__ (-1021)
-// PPC-AIX:#define __DBL_MIN__ 2.2250738585072014e-308
-// PPC-AIX:#define __DECIMAL_DIG__ __LDBL_DECIMAL_DIG__
-// PPC-AIX:#define __FLT_DENORM_MIN__ 1.40129846e-45F
-// PPC-AIX:#define __FLT_DIG__ 6
-// PPC-AIX:#define __FLT_EPSILON__ 1.19209290e-7F
-// PPC-AIX:#define __FLT_EVAL_METHOD__ 1
-// PPC-AIX:#define __FLT_HAS_DENORM__ 1
-// PPC-AIX:#define __FLT_HAS_INFINITY__ 1
-// PPC-AIX:#define __FLT_HAS_QUIET_NAN__ 1
-// PPC-AIX:#define __FLT_MANT_DIG__ 24
-// PPC-AIX:#define __FLT_MAX_10_EXP__ 38
-// PPC-AIX:#define __FLT_MAX_EXP__ 128
-// PPC-AIX:#define __FLT_MAX__ 3.40282347e+38F
-// PPC-AIX:#define __FLT_MIN_10_EXP__ (-37)
-// PPC-AIX:#define __FLT_MIN_EXP__ (-125)
-// PPC-AIX:#define __FLT_MIN__ 1.17549435e-38F
-// PPC-AIX:#define __FLT_RADIX__ 2
-// PPC-AIX:#define __INT16_C_SUFFIX__
-// PPC-AIX:#define __INT16_FMTd__ "hd"
-// PPC-AIX:#define __INT16_FMTi__ "hi"
-// PPC-AIX:#define __INT16_MAX__ 32767
-// PPC-AIX:#define __INT16_TYPE__ short
-// PPC-AIX:#define __INT32_C_SUFFIX__
-// PPC-AIX:#define __INT32_FMTd__ "d"
-// PPC-AIX:#define __INT32_FMTi__ "i"
-// PPC-AIX:#define __INT32_MAX__ 2147483647
-// PPC-AIX:#define __INT32_TYPE__ int
-// PPC-AIX:#define __INT64_C_SUFFIX__ LL
-// PPC-AIX:#define __INT64_FMTd__ "lld"
-// PPC-AIX:#define __INT64_FMTi__ "lli"
-// PPC-AIX:#define __INT64_MAX__ 9223372036854775807LL
-// PPC-AIX:#define __INT64_TYPE__ long long int
-// PPC-AIX:#define __INT8_C_SUFFIX__
-// PPC-AIX:#define __INT8_FMTd__ "hhd"
-// PPC-AIX:#define __INT8_FMTi__ "hhi"
-// PPC-AIX:#define __INT8_MAX__ 127
-// PPC-AIX:#define __INT8_TYPE__ signed char
-// PPC-AIX:#define __INTMAX_C_SUFFIX__ LL
-// PPC-AIX:#define __INTMAX_FMTd__ "lld"
-// PPC-AIX:#define __INTMAX_FMTi__ "lli"
-// PPC-AIX:#define __INTMAX_MAX__ 9223372036854775807LL
-// PPC-AIX:#define __INTMAX_TYPE__ long long int
-// PPC-AIX:#define __INTMAX_WIDTH__ 64
-// PPC-AIX:#define __INTPTR_FMTd__ "ld"
-// PPC-AIX:#define __INTPTR_FMTi__ "li"
-// PPC-AIX:#define __INTPTR_MAX__ 2147483647L
-// PPC-AIX:#define __INTPTR_TYPE__ long int
-// PPC-AIX:#define __INTPTR_WIDTH__ 32
-// PPC-AIX:#define __INT_FAST16_FMTd__ "hd"
-// PPC-AIX:#define __INT_FAST16_FMTi__ "hi"
-// PPC-AIX:#define __INT_FAST16_MAX__ 32767
-// PPC-AIX:#define __INT_FAST16_TYPE__ short
-// PPC-AIX:#define __INT_FAST32_FMTd__ "d"
-// PPC-AIX:#define __INT_FAST32_FMTi__ "i"
-// PPC-AIX:#define __INT_FAST32_MAX__ 2147483647
-// PPC-AIX:#define __INT_FAST32_TYPE__ int
-// PPC-AIX:#define __INT_FAST64_FMTd__ "lld"
-// PPC-AIX:#define __INT_FAST64_FMTi__ "lli"
-// PPC-AIX:#define __INT_FAST64_MAX__ 9223372036854775807LL
-// PPC-AIX:#define __INT_FAST64_TYPE__ long long int
-// PPC-AIX:#define __INT_FAST8_FMTd__ "hhd"
-// PPC-AIX:#define __INT_FAST8_FMTi__ "hhi"
-// PPC-AIX:#define __INT_FAST8_MAX__ 127
-// PPC-AIX:#define __INT_FAST8_TYPE__ signed char
-// PPC-AIX:#define __INT_LEAST16_FMTd__ "hd"
-// PPC-AIX:#define __INT_LEAST16_FMTi__ "hi"
-// PPC-AIX:#define __INT_LEAST16_MAX__ 32767
-// PPC-AIX:#define __INT_LEAST16_TYPE__ short
-// PPC-AIX:#define __INT_LEAST32_FMTd__ "d"
-// PPC-AIX:#define __INT_LEAST32_FMTi__ "i"
-// PPC-AIX:#define __INT_LEAST32_MAX__ 2147483647
-// PPC-AIX:#define __INT_LEAST32_TYPE__ int
-// PPC-AIX:#define __INT_LEAST64_FMTd__ "lld"
-// PPC-AIX:#define __INT_LEAST64_FMTi__ "lli"
-// PPC-AIX:#define __INT_LEAST64_MAX__ 9223372036854775807LL
-// PPC-AIX:#define __INT_LEAST64_TYPE__ long long int
-// PPC-AIX:#define __INT_LEAST8_FMTd__ "hhd"
-// PPC-AIX:#define __INT_LEAST8_FMTi__ "hhi"
-// PPC-AIX:#define __INT_LEAST8_MAX__ 127
-// PPC-AIX:#define __INT_LEAST8_TYPE__ signed char
-// PPC-AIX:#define __INT_MAX__ 2147483647
-// PPC-AIX:#define __LDBL_DECIMAL_DIG__ 17
-// PPC-AIX:#define __LDBL_DENORM_MIN__ 4.9406564584124654e-324L
-// PPC-AIX:#define __LDBL_DIG__ 15
-// PPC-AIX:#define __LDBL_EPSILON__ 2.2204460492503131e-16L
-// PPC-AIX:#define __LDBL_HAS_DENORM__ 1
-// PPC-AIX:#define __LDBL_HAS_INFINITY__ 1
-// PPC-AIX:#define __LDBL_HAS_QUIET_NAN__ 1
-// PPC-AIX:#define __LDBL_MANT_DIG__ 53
-// PPC-AIX:#define __LDBL_MAX_10_EXP__ 308
-// PPC-AIX:#define __LDBL_MAX_EXP__ 1024
-// PPC-AIX:#define __LDBL_MAX__ 1.7976931348623157e+308L
-// PPC-AIX:#define __LDBL_MIN_10_EXP__ (-307)
-// PPC-AIX:#define __LDBL_MIN_EXP__ (-1021)
-// PPC-AIX:#define __LDBL_MIN__ 2.2250738585072014e-308L
-// PPC-AIX:#define __LONG_LONG_MAX__ 9223372036854775807LL
-// PPC-AIX:#define __LONG_MAX__ 2147483647L
-// PPC-AIX-NOT:#define __LP64__ 1
-// PPC-AIX-NOT:#define __NATURAL_ALIGNMENT__ 1
-// PPC-AIX:#define __POINTER_WIDTH__ 32
-// PPC-AIX:#define __POWERPC__ 1
-// PPC-AIX:#define __PPC__ 1
-// PPC-AIX:#define __PTRDIFF_TYPE__ long int
-// PPC-AIX:#define __PTRDIFF_WIDTH__ 32
-// PPC-AIX:#define __REGISTER_PREFIX__
-// PPC-AIX:#define __SCHAR_MAX__ 127
-// PPC-AIX:#define __SHRT_MAX__ 32767
-// PPC-AIX:#define __SIG_ATOMIC_MAX__ 2147483647
-// PPC-AIX:#define __SIG_ATOMIC_WIDTH__ 32
-// PPC-AIX:#define __SIZEOF_DOUBLE__ 8
-// PPC-AIX:#define __SIZEOF_FLOAT__ 4
-// PPC-AIX:#define __SIZEOF_INT__ 4
-// PPC-AIX:#define __SIZEOF_LONG_DOUBLE__ 8
-// PPC-AIX:#define __SIZEOF_LONG_LONG__ 8
-// PPC-AIX:#define __SIZEOF_LONG__ 4
-// PPC-AIX:#define __SIZEOF_POINTER__ 4
-// PPC-AIX:#define __SIZEOF_PTRDIFF_T__ 4
-// PPC-AIX:#define __SIZEOF_SHORT__ 2
-// PPC-AIX:#define __SIZEOF_SIZE_T__ 4
-// PPC-AIX:#define __SIZEOF_WCHAR_T__ 2
-// PPC-AIX:#define __SIZEOF_WINT_T__ 4
-// PPC-AIX:#define __SIZE_MAX__ 4294967295UL
-// PPC-AIX:#define __SIZE_TYPE__ long unsigned int
-// PPC-AIX:#define __SIZE_WIDTH__ 32
-// PPC-AIX:#define __UINT16_C_SUFFIX__
-// PPC-AIX:#define __UINT16_MAX__ 65535
-// PPC-AIX:#define __UINT16_TYPE__ unsigned short
-// PPC-AIX:#define __UINT32_C_SUFFIX__ U
-// PPC-AIX:#define __UINT32_MAX__ 4294967295U
-// PPC-AIX:#define __UINT32_TYPE__ unsigned int
-// PPC-AIX:#define __UINT64_C_SUFFIX__ ULL
-// PPC-AIX:#define __UINT64_MAX__ 18446744073709551615ULL
-// PPC-AIX:#define __UINT64_TYPE__ long long unsigned int
-// PPC-AIX:#define __UINT8_C_SUFFIX__
-// PPC-AIX:#define __UINT8_MAX__ 255
-// PPC-AIX:#define __UINT8_TYPE__ unsigned char
-// PPC-AIX:#define __UINTMAX_C_SUFFIX__ ULL
-// PPC-AIX:#define __UINTMAX_MAX__ 18446744073709551615ULL
-// PPC-AIX:#define __UINTMAX_TYPE__ long long unsigned int
-// PPC-AIX:#define __UINTMAX_WIDTH__ 64
-// PPC-AIX:#define __UINTPTR_MAX__ 4294967295UL
-// PPC-AIX:#define __UINTPTR_TYPE__ long unsigned int
-// PPC-AIX:#define __UINTPTR_WIDTH__ 32
-// PPC-AIX:#define __UINT_FAST16_MAX__ 65535
-// PPC-AIX:#define __UINT_FAST16_TYPE__ unsigned short
-// PPC-AIX:#define __UINT_FAST32_MAX__ 4294967295U
-// PPC-AIX:#define __UINT_FAST32_TYPE__ unsigned int
-// PPC-AIX:#define __UINT_FAST64_MAX__ 18446744073709551615ULL
-// PPC-AIX:#define __UINT_FAST64_TYPE__ long long unsigned int
-// PPC-AIX:#define __UINT_FAST8_MAX__ 255
-// PPC-AIX:#define __UINT_FAST8_TYPE__ unsigned char
-// PPC-AIX:#define __UINT_LEAST16_MAX__ 65535
-// PPC-AIX:#define __UINT_LEAST16_TYPE__ unsigned short
-// PPC-AIX:#define __UINT_LEAST32_MAX__ 4294967295U
-// PPC-AIX:#define __UINT_LEAST32_TYPE__ unsigned int
-// PPC-AIX:#define __UINT_LEAST64_MAX__ 18446744073709551615ULL
-// PPC-AIX:#define __UINT_LEAST64_TYPE__ long long unsigned int
-// PPC-AIX:#define __UINT_LEAST8_MAX__ 255
-// PPC-AIX:#define __UINT_LEAST8_TYPE__ unsigned char
-// PPC-AIX:#define __USER_LABEL_PREFIX__
-// PPC-AIX:#define __WCHAR_MAX__ 65535
-// PPC-AIX:#define __WCHAR_TYPE__ unsigned short
-// PPC-AIX:#define __WCHAR_WIDTH__ 16
-// PPC-AIX:#define __WINT_TYPE__ int
-// PPC-AIX:#define __WINT_WIDTH__ 32
-// PPC-AIX:#define __powerpc__ 1
-// PPC-AIX:#define __ppc__ 1
-//
-// RUN: %clang_cc1 -x c++ -E -dM -ffreestanding -triple=powerpc-ibm-aix7.1.0.0 -fno-signed-char < /dev/null | FileCheck -match-full-lines -check-prefix PPC-AIX-CXX %s
-//
-// PPC-AIX-CXX:#define _WCHAR_T 1
-//
-// RUN: %clang_cc1 -x c++ -fno-wchar -E -dM -ffreestanding -triple=powerpc-ibm-aix7.1.0.0 < /dev/null | FileCheck -match-full-lines -check-prefix PPC-AIX-NOWCHAR %s
-// RUN: %clang_cc1 -x c -E -dM -ffreestanding -triple=powerpc-ibm-aix7.1.0.0 < /dev/null | FileCheck -match-full-lines -check-prefix PPC-AIX-NOWCHAR %s
-//
-// PPC-AIX-NOWCHAR-NOT:#define _WCHAR_T 1
-//
-// RUN: %clang_cc1 -E -dM -ffreestanding -triple=powerpc-ibm-aix7.1.0.0 -fno-signed-char -pthread < /dev/null | FileCheck -match-full-lines -check-prefix PPC-AIX-THREADSAFE %s
-// PPC-AIX-THREADSAFE:#define _THREAD_SAFE 1
-//
-// RUN: %clang_cc1 -E -dM -ffreestanding -triple=powerpc-ibm-aix7.1.0.0 -fno-signed-char < /dev/null | FileCheck -match-full-lines -check-prefix PPC-AIX-NOTHREADSAFE %s
-// PPC-AIX-NOTHREADSAFE-NOT:#define _THREAD_SAFE 1
-//
 // RUN: %clang_cc1 -E -dM -ffreestanding -triple=powerpc-unknown-linux-gnu -fno-signed-char < /dev/null | FileCheck -match-full-lines -check-prefix PPC-LINUX %s
 //
 // PPC-LINUX:#define _ARCH_PPC 1
@@ -8973,17 +8532,6 @@
 // X86_64-LINUX:#define __FLT_MIN_EXP__ (-125)
 // X86_64-LINUX:#define __FLT_MIN__ 1.17549435e-38F
 // X86_64-LINUX:#define __FLT_RADIX__ 2
-// X86_64-LINUX:#define __GCC_ATOMIC_BOOL_LOCK_FREE 2
-// X86_64-LINUX:#define __GCC_ATOMIC_CHAR16_T_LOCK_FREE 2
-// X86_64-LINUX:#define __GCC_ATOMIC_CHAR32_T_LOCK_FREE 2
-// X86_64-LINUX:#define __GCC_ATOMIC_CHAR_LOCK_FREE 2
-// X86_64-LINUX:#define __GCC_ATOMIC_INT_LOCK_FREE 2
-// X86_64-LINUX:#define __GCC_ATOMIC_LLONG_LOCK_FREE 2
-// X86_64-LINUX:#define __GCC_ATOMIC_LONG_LOCK_FREE 2
-// X86_64-LINUX:#define __GCC_ATOMIC_POINTER_LOCK_FREE 2
-// X86_64-LINUX:#define __GCC_ATOMIC_SHORT_LOCK_FREE 2
-// X86_64-LINUX:#define __GCC_ATOMIC_TEST_AND_SET_TRUEVAL 1
-// X86_64-LINUX:#define __GCC_ATOMIC_WCHAR_T_LOCK_FREE 2
 // X86_64-LINUX:#define __INT16_C_SUFFIX__
 // X86_64-LINUX:#define __INT16_FMTd__ "hd"
 // X86_64-LINUX:#define __INT16_FMTi__ "hi"
@@ -9186,17 +8734,6 @@
 // X86_64-NETBSD:#define __FLT_MIN_EXP__ (-125)
 // X86_64-NETBSD:#define __FLT_MIN__ 1.17549435e-38F
 // X86_64-NETBSD:#define __FLT_RADIX__ 2
-// X86_64-NETBSD:#define __GCC_ATOMIC_BOOL_LOCK_FREE 2
-// X86_64-NETBSD:#define __GCC_ATOMIC_CHAR16_T_LOCK_FREE 2
-// X86_64-NETBSD:#define __GCC_ATOMIC_CHAR32_T_LOCK_FREE 2
-// X86_64-NETBSD:#define __GCC_ATOMIC_CHAR_LOCK_FREE 2
-// X86_64-NETBSD:#define __GCC_ATOMIC_INT_LOCK_FREE 2
-// X86_64-NETBSD:#define __GCC_ATOMIC_LLONG_LOCK_FREE 2
-// X86_64-NETBSD:#define __GCC_ATOMIC_LONG_LOCK_FREE 2
-// X86_64-NETBSD:#define __GCC_ATOMIC_POINTER_LOCK_FREE 2
-// X86_64-NETBSD:#define __GCC_ATOMIC_SHORT_LOCK_FREE 2
-// X86_64-NETBSD:#define __GCC_ATOMIC_TEST_AND_SET_TRUEVAL 1
-// X86_64-NETBSD:#define __GCC_ATOMIC_WCHAR_T_LOCK_FREE 2
 // X86_64-NETBSD:#define __INT16_C_SUFFIX__
 // X86_64-NETBSD:#define __INT16_FMTd__ "hd"
 // X86_64-NETBSD:#define __INT16_FMTi__ "hi"
@@ -9629,20 +9166,20 @@
 // WEBASSEMBLY-NOT:#define __ELF__
 // WEBASSEMBLY-NEXT:#define __FINITE_MATH_ONLY__ 0
 // WEBASSEMBLY-NEXT:#define __FLOAT128__ 1
-// WEBASSEMBLY-NOT:#define __FLT16_DECIMAL_DIG__
-// WEBASSEMBLY-NOT:#define __FLT16_DENORM_MIN__
-// WEBASSEMBLY-NOT:#define __FLT16_DIG__
-// WEBASSEMBLY-NOT:#define __FLT16_EPSILON__
-// WEBASSEMBLY-NOT:#define __FLT16_HAS_DENORM__
-// WEBASSEMBLY-NOT:#define __FLT16_HAS_INFINITY__
-// WEBASSEMBLY-NOT:#define __FLT16_HAS_QUIET_NAN__
-// WEBASSEMBLY-NOT:#define __FLT16_MANT_DIG__
-// WEBASSEMBLY-NOT:#define __FLT16_MAX_10_EXP__
-// WEBASSEMBLY-NOT:#define __FLT16_MAX_EXP__
-// WEBASSEMBLY-NOT:#define __FLT16_MAX__
-// WEBASSEMBLY-NOT:#define __FLT16_MIN_10_EXP__
-// WEBASSEMBLY-NOT:#define __FLT16_MIN_EXP__
-// WEBASSEMBLY-NOT:#define __FLT16_MIN__
+// WEBASSEMBLY-NEXT:#define __FLT16_DECIMAL_DIG__ 5
+// WEBASSEMBLY-NEXT:#define __FLT16_DENORM_MIN__ 5.9604644775390625e-8F16
+// WEBASSEMBLY-NEXT:#define __FLT16_DIG__ 3
+// WEBASSEMBLY-NEXT:#define __FLT16_EPSILON__ 9.765625e-4F16
+// WEBASSEMBLY-NEXT:#define __FLT16_HAS_DENORM__ 1
+// WEBASSEMBLY-NEXT:#define __FLT16_HAS_INFINITY__ 1
+// WEBASSEMBLY-NEXT:#define __FLT16_HAS_QUIET_NAN__ 1
+// WEBASSEMBLY-NEXT:#define __FLT16_MANT_DIG__ 11
+// WEBASSEMBLY-NEXT:#define __FLT16_MAX_10_EXP__ 4
+// WEBASSEMBLY-NEXT:#define __FLT16_MAX_EXP__ 15
+// WEBASSEMBLY-NEXT:#define __FLT16_MAX__ 6.5504e+4F16
+// WEBASSEMBLY-NEXT:#define __FLT16_MIN_10_EXP__ (-13)
+// WEBASSEMBLY-NEXT:#define __FLT16_MIN_EXP__ (-14)
+// WEBASSEMBLY-NEXT:#define __FLT16_MIN__ 6.103515625e-5F16
 // WEBASSEMBLY-NEXT:#define __FLT_DECIMAL_DIG__ 9
 // WEBASSEMBLY-NEXT:#define __FLT_DENORM_MIN__ 1.40129846e-45F
 // WEBASSEMBLY-NEXT:#define __FLT_DIG__ 6
@@ -9675,6 +9212,7 @@
 // WEBASSEMBLY-NEXT:#define __GNUC_STDC_INLINE__ 1
 // WEBASSEMBLY-NEXT:#define __GNUC__ {{.*}}
 // WEBASSEMBLY-NEXT:#define __GXX_ABI_VERSION 1002
+// WEBASSEMBLY-NEXT:#define __HAVE_SPECULATION_SAFE_VALUE 1
 // WEBASSEMBLY32-NEXT:#define __ILP32__ 1
 // WEBASSEMBLY64-NOT:#define __ILP32__
 // WEBASSEMBLY-NEXT:#define __INT16_C_SUFFIX__
Index: clang/test/CodeGen/builtin-speculation-safe-value.c
===================================================================
--- /dev/null
+++ clang/test/CodeGen/builtin-speculation-safe-value.c
@@ -0,0 +1,19 @@
+// REQUIRES: x86-registered-target
+// RUN: %clang_cc1 -triple x86_64-linux-gnu -emit-llvm %s -o - | FileCheck -check-prefix=CHECK-SUPPORTED %s
+
+void test(char c, int i, void *p) {
+  // CHECK-LABEL-SUPPORTED: define void @test
+
+  char c_safe = __builtin_speculation_safe_value(c);
+  // CHECK-SUPPORTED: call i8 @llvm.speculationsafevalue.i8(i8 %{{[0-9a-z]+}})
+
+  int i_safe = __builtin_speculation_safe_value(i);
+  // CHECK-SUPPORTED: call i32 @llvm.speculationsafevalue.i32(i32 %{{[0-9a-z]+}})
+
+  void *p_safe = __builtin_speculation_safe_value(p);
+  // CHECK-SUPPORTED: call i8* @llvm.speculationsafevalue.p0i8(i8* %{{[0-9a-z]+}})
+
+  int arr[4];
+  int *arr_safe = __builtin_speculation_safe_value(arr);
+  // CHECK-SUPPORTED: call i32* @llvm.speculationsafevalue.p0i32(i32* %{{[0-9a-z]+}})
+}
Index: clang/lib/Sema/SemaChecking.cpp
===================================================================
--- clang/lib/Sema/SemaChecking.cpp
+++ clang/lib/Sema/SemaChecking.cpp
@@ -1492,6 +1492,8 @@
     if (SemaBuiltinOSLogFormat(TheCall))
       return ExprError();
     break;
+  case Builtin::BI__builtin_speculation_safe_value:
+   return SemaBuiltinSpeculationSafeValueOverloaded(TheCallResult);
   }
 
   // Since the target specific builtins for each arch overlap, only check those
@@ -5307,6 +5309,44 @@
   return TheCallResult;
 }
 
+ExprResult Sema::SemaBuiltinSpeculationSafeValueOverloaded(ExprResult TheCallResult) {
+  CallExpr *TheCall = (CallExpr *) TheCallResult.get();
+  DeclRefExpr *DRE = cast<DeclRefExpr>(TheCall->getCallee()->IgnoreParenCasts());
+  FunctionDecl *FDecl = cast<FunctionDecl>(DRE->getDecl());
+  unsigned BuiltinID = FDecl->getBuiltinID();
+  assert(BuiltinID == Builtin::BI__builtin_speculation_safe_value && "Unexpected speculation_Safe_value builtin!");
+
+  // Too few args
+  if (TheCall->getNumArgs() < 1)
+    return Diag(TheCall->getEndLoc(), diag::err_typecheck_call_too_few_args_at_least)
+      << 0 /*function call*/ << 1 /* min args */ << TheCall->getNumArgs();
+
+  // Too many args
+  if (TheCall->getNumArgs() < 1)
+    return Diag(TheCall->getEndLoc(), diag::err_typecheck_call_too_many_args_at_most)
+      << 0 /*function call*/ << 1 << TheCall->getNumArgs()
+      << SourceRange(TheCall->getArg(1)->getBeginLoc(),
+      (*(TheCall->arg_end() - 1))->getEndLoc());
+
+  // Derive the return type from the pointer argument
+  ExprResult FirstArg = DefaultFunctionArrayLvalueConversion(TheCall->getArg(0));
+  if (FirstArg.isInvalid())
+    return true;
+  TheCall->setArg(0, FirstArg.get());
+  QualType FirstArgType = FirstArg.get()->getType();
+
+  TheCall->setType(FirstArgType);
+
+  // The first argument must be a pointer or integer type.
+  if (!(FirstArgType->isIntegerType() || FirstArgType->isAnyPointerType()))
+    return Diag(TheCall->getArg(0)->getBeginLoc(),
+      diag::err_specsafevalue_builtin_must_be_pointer_or_integral)
+        << TheCall->getArg(0)->getType()
+        << TheCall->getArg(0)->getSourceRange();
+
+  return TheCallResult;
+}
+
 /// CheckObjCString - Checks that the argument to the builtin
 /// CFString constructor is correct
 /// Note: It might also make sense to do the UTF-16 conversion here (would
Index: clang/lib/Frontend/InitPreprocessor.cpp
===================================================================
--- clang/lib/Frontend/InitPreprocessor.cpp
+++ clang/lib/Frontend/InitPreprocessor.cpp
@@ -1083,6 +1083,8 @@
     Builder.defineMacro("__GLIBCXX_BITSIZE_INT_N_0", "128");
   }
 
+  Builder.defineMacro("__HAVE_SPECULATION_SAFE_VALUE");
+
   // Get other target #defines.
   TI.getTargetDefines(LangOpts, Builder);
 }
Index: clang/lib/CodeGen/CGBuiltin.cpp
===================================================================
--- clang/lib/CodeGen/CGBuiltin.cpp
+++ clang/lib/CodeGen/CGBuiltin.cpp
@@ -10,6 +10,7 @@
 //
 //===----------------------------------------------------------------------===//
 
+#include "/usr/local/google/home/zbrid/repos/llvm-project/clang/lib/CodeGen/CodeGenTypeCache.h"
 #include "CGCXXABI.h"
 #include "CGObjCRuntime.h"
 #include "CGOpenCLRuntime.h"
@@ -3939,6 +3940,15 @@
     Value *ArgPtr = Builder.CreateLoad(SrcAddr, "ap.val");
     return RValue::get(Builder.CreateStore(ArgPtr, DestAddr));
   }
+  case Builtin::BI__builtin_speculation_safe_value: {
+    Value *Val = EmitScalarExpr(E->getArg(0));
+
+    llvm::Type *T = ConvertType(E->getType());
+    assert((isa<llvm::IntegerType>(T) || isa<llvm::PointerType>(T)) && "unsupported type");
+
+    return RValue::get(Builder.CreateCall(
+        CGM.getIntrinsic(Intrinsic::speculationsafevalue, T), {Val}));
+  }
   }
 
   // If this is an alias for a lib function (e.g. __builtin_sin), emit
Index: clang/include/clang/Sema/Sema.h
===================================================================
--- clang/include/clang/Sema/Sema.h
+++ clang/include/clang/Sema/Sema.h
@@ -10712,6 +10712,7 @@
                                      AtomicExpr::AtomicOp Op);
   ExprResult SemaBuiltinOperatorNewDeleteOverloaded(ExprResult TheCallResult,
                                                     bool IsDelete);
+  ExprResult SemaBuiltinSpeculationSafeValueOverloaded(ExprResult TheCallResult);
   bool SemaBuiltinConstantArg(CallExpr *TheCall, int ArgNum,
                               llvm::APSInt &Result);
   bool SemaBuiltinConstantArgRange(CallExpr *TheCall, int ArgNum, int Low,
Index: clang/include/clang/Basic/DiagnosticSemaKinds.td
===================================================================
--- clang/include/clang/Basic/DiagnosticSemaKinds.td
+++ clang/include/clang/Basic/DiagnosticSemaKinds.td
@@ -9553,6 +9553,10 @@
    "the type is not trivially copyable|"
    "the type does not have the expected form}1">;
 
+def err_specsafevalue_builtin_must_be_pointer_or_integral : Error<
+  "argument to speculation_safe_value builtin must be a pointer or integer "
+  "(%0 invalid)">;
+
 def warn_dereference_of_noderef_type : Warning<
   "dereferencing %0; was declared with a 'noderef' type">, InGroup<NoDeref>;
 def warn_dereference_of_noderef_type_no_decl : Warning<
Index: clang/include/clang/Basic/Builtins.def
===================================================================
--- clang/include/clang/Basic/Builtins.def
+++ clang/include/clang/Basic/Builtins.def
@@ -1525,6 +1525,9 @@
 BUILTIN(__builtin_ms_va_end, "vc*&", "n")
 BUILTIN(__builtin_ms_va_copy, "vc*&c*&", "n")
 
+// T __builtin_speculation_safe_value (T val)
+BUILTIN(__builtin_speculation_safe_value, "vv", "t")
+
 #undef BUILTIN
 #undef LIBBUILTIN
 #undef LANGBUILTIN
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to