@@ -1115,15 +1115,36 @@ impl<'ll, 'tcx, 'a> BuilderMethods<'a, 'tcx> for Builder<'a, 'll, 'tcx> {
1115
1115
) -> ( & ' ll Value , & ' ll Value ) {
1116
1116
// LLVM verifier rejects cases where the `failure_order` is stronger than `order`
1117
1117
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 )
1122
1129
| ( 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
1123
1145
( 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 ) => {
1127
1148
self . abort ( ) ;
1128
1149
return (
1129
1150
self . const_undef ( self . val_ty ( cmp) ) ,
@@ -1692,6 +1713,7 @@ impl<'a, 'll, 'tcx> Builder<'a, 'll, 'tcx> {
1692
1713
impl < ' ll , ' tcx , ' a > Builder < ' a , ' ll , ' tcx > {
1693
1714
/// Implements a standard atomic, using LLVM intrinsics(in `atomic_supported`, if `dst` is in a supported address space)
1694
1715
/// 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.
1695
1717
fn atomic_op (
1696
1718
& mut self ,
1697
1719
dst : & ' ll Value ,
0 commit comments