@@ -1115,15 +1115,36 @@ impl<'ll, 'tcx, 'a> BuilderMethods<'a, 'tcx> for Builder<'a, 'll, 'tcx> {
11151115 ) -> ( & ' ll Value , & ' ll Value ) {
11161116 // LLVM verifier rejects cases where the `failure_order` is stronger than `order`
11171117 match ( order, failure_order) {
1118- ( AtomicOrdering :: SeqCst , _) => ( ) ,
1119- ( _, AtomicOrdering :: Relaxed ) => ( ) ,
1120- ( AtomicOrdering :: Release , AtomicOrdering :: Release )
1121- | ( AtomicOrdering :: Release , AtomicOrdering :: Acquire )
1118+ // Failure order `Release` & `AcqRel` is simply invalid.
1119+ ( _, AtomicOrdering :: Release | AtomicOrdering :: AcqRel ) => {
1120+ self . abort ( ) ;
1121+ return (
1122+ self . const_undef ( self . val_ty ( cmp) ) ,
1123+ self . const_undef ( self . type_i1 ( ) ) ,
1124+ ) ;
1125+ }
1126+ // Success & failure ordering are the same - OK.
1127+ ( AtomicOrdering :: SeqCst , AtomicOrdering :: SeqCst )
1128+ | ( AtomicOrdering :: Relaxed , AtomicOrdering :: Relaxed )
11221129 | ( AtomicOrdering :: Acquire , AtomicOrdering :: Acquire ) => ( ) ,
1130+ // Failure is `SeqCst`(strongest) & success is anything else(weaker) - reject.
1131+ ( _, AtomicOrdering :: SeqCst ) => {
1132+ self . abort ( ) ;
1133+ return (
1134+ self . const_undef ( self . val_ty ( cmp) ) ,
1135+ self . const_undef ( self . type_i1 ( ) ) ,
1136+ ) ;
1137+ }
1138+ // Failure is Relaxed(weakest), and success is anything - OK.
1139+ ( _, AtomicOrdering :: Relaxed ) => ( ) ,
1140+ // Failure is anything, and success is SeqCest(strongest) - OK.
1141+ ( AtomicOrdering :: SeqCst , _) => ( ) ,
1142+ // Failure is Acquire, and success is Release - OK.
1143+ ( AtomicOrdering :: Release , AtomicOrdering :: Acquire ) => ( ) ,
1144+ // Success is AcqRel & failure is Acquire - OK
11231145 ( AtomicOrdering :: AcqRel , AtomicOrdering :: Acquire ) => ( ) ,
1124- ( AtomicOrdering :: Relaxed , _)
1125- | ( _, AtomicOrdering :: Release | AtomicOrdering :: AcqRel | AtomicOrdering :: SeqCst ) => {
1126- // Invalid cmpxchg - `failure_order` is stronger than `order`! So, we abort.
1146+ // Success is weaker than failure - reject.
1147+ ( AtomicOrdering :: Relaxed , AtomicOrdering :: Acquire ) => {
11271148 self . abort ( ) ;
11281149 return (
11291150 self . const_undef ( self . val_ty ( cmp) ) ,
@@ -1692,6 +1713,7 @@ impl<'a, 'll, 'tcx> Builder<'a, 'll, 'tcx> {
16921713impl < ' ll , ' tcx , ' a > Builder < ' a , ' ll , ' tcx > {
16931714 /// Implements a standard atomic, using LLVM intrinsics(in `atomic_supported`, if `dst` is in a supported address space)
16941715 /// or emulation(with `emulate_local`, if `dst` points to a thread-local address space).
1716+ /// FIXME(FractalFir): this code assumess all pointers are generic. Adjust it once we support address spaces.
16951717 fn atomic_op (
16961718 & mut self ,
16971719 dst : & ' ll Value ,
0 commit comments