Index: lib/CodeGen/CodeGenPrepare.cpp =================================================================== --- lib/CodeGen/CodeGenPrepare.cpp +++ lib/CodeGen/CodeGenPrepare.cpp @@ -1397,6 +1397,16 @@ } return false; } + case Intrinsic::aarch64_stlxr: + case Intrinsic::aarch64_stxr: { + ZExtInst *ExtVal = dyn_cast(CI->getArgOperand(0)); + if (!ExtVal || !ExtVal->hasOneUse() || + ExtVal->getParent() == CI->getParent()) + return false; + // Sink a zext feeding stlxr/stxr before it, so it can be folded into it. + ExtVal->moveBefore(CI); + return true; + } } if (TLI) { Index: test/CodeGen/AArch64/arm64-atomic.ll =================================================================== --- test/CodeGen/AArch64/arm64-atomic.ll +++ test/CodeGen/AArch64/arm64-atomic.ll @@ -2,12 +2,11 @@ define i32 @val_compare_and_swap(i32* %p, i32 %cmp, i32 %new) { ; CHECK-LABEL: val_compare_and_swap: -; CHECK: ubfx x[[NEWVAL_REG:[0-9]+]], x2, #0, #32 ; CHECK: [[LABEL:.?LBB[0-9]+_[0-9]+]]: ; CHECK: ldaxr [[RESULT:w[0-9]+]], [x0] ; CHECK: cmp [[RESULT]], w1 ; CHECK: b.ne [[LABEL2:.?LBB[0-9]+_[0-9]+]] -; CHECK: stxr [[SCRATCH_REG:w[0-9]+]], w[[NEWVAL_REG]], [x0] +; CHECK: stxr [[SCRATCH_REG:w[0-9]+]], w2, [x0] ; CHECK: cbnz [[SCRATCH_REG]], [[LABEL]] ; CHECK: [[LABEL2]]: %pair = cmpxchg i32* %p, i32 %cmp, i32 %new acquire acquire @@ -17,12 +16,11 @@ define i32 @val_compare_and_swap_rel(i32* %p, i32 %cmp, i32 %new) { ; CHECK-LABEL: val_compare_and_swap_rel: -; CHECK: ubfx x[[NEWVAL_REG:[0-9]+]], x2, #0, #32 ; CHECK: [[LABEL:.?LBB[0-9]+_[0-9]+]]: ; CHECK: ldaxr [[RESULT:w[0-9]+]], [x0] ; CHECK: cmp [[RESULT]], w1 ; CHECK: b.ne [[LABEL2:.?LBB[0-9]+_[0-9]+]] -; CHECK: stlxr [[SCRATCH_REG:w[0-9]+]], w[[NEWVAL_REG]], [x0] +; CHECK: stlxr [[SCRATCH_REG:w[0-9]+]], w2, [x0] ; CHECK: cbnz [[SCRATCH_REG]], [[LABEL]] ; CHECK: [[LABEL2]]: %pair = cmpxchg i32* %p, i32 %cmp, i32 %new acq_rel monotonic