Serguei Katkov 15f1cffb3a [MemoryDependency] Relax the re-ordering with volatile store.
Volatile store does not provide any special rules for reordering with
atomics. Usual must alias anaylsis is enough here.

This makes the bahavior similar to how volatile load is handled.

Reviewers: reames, nikic
Reviewed By: reames
Subscribers: llvm-commits
Differential Revision: https://reviews.llvm.org/D119818
2022-02-16 10:58:48 +07:00

95 lines
3.3 KiB
LLVM

; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
; RUN: opt -S -gvn --basic-aa < %s | FileCheck %s
@u = global i32 5, align 4
@w = global i32 10, align 4
define i32 @test_load() {
; CHECK-LABEL: @test_load(
; CHECK-NEXT: [[LV:%.*]] = load volatile i32, i32* @u, align 4
; CHECK-NEXT: ret i32 [[LV]]
;
%l1 = load atomic i32, i32* @w unordered, align 4
%lv = load volatile i32, i32* @u, align 4
%l2 = load atomic i32, i32* @w unordered, align 4
%res.1 = sub i32 %l1, %l2
%res = add i32 %res.1, %lv
ret i32 %res
}
define i32 @test_load_with_acquire_load() {
; CHECK-LABEL: @test_load_with_acquire_load(
; CHECK-NEXT: [[L1:%.*]] = load atomic i32, i32* @w acquire, align 4
; CHECK-NEXT: [[LV:%.*]] = load volatile i32, i32* @u, align 4
; CHECK-NEXT: [[L2:%.*]] = load atomic i32, i32* @w acquire, align 4
; CHECK-NEXT: [[RES_1:%.*]] = sub i32 [[L1]], [[L2]]
; CHECK-NEXT: [[RES:%.*]] = add i32 [[RES_1]], [[LV]]
; CHECK-NEXT: ret i32 [[RES]]
;
%l1 = load atomic i32, i32* @w acquire, align 4
%lv = load volatile i32, i32* @u, align 4
%l2 = load atomic i32, i32* @w acquire, align 4
%res.1 = sub i32 %l1, %l2
%res = add i32 %res.1, %lv
ret i32 %res
}
define i32 @test_load_with_seq_cst_load() {
; CHECK-LABEL: @test_load_with_seq_cst_load(
; CHECK-NEXT: [[L1:%.*]] = load atomic i32, i32* @w seq_cst, align 4
; CHECK-NEXT: [[LV:%.*]] = load volatile i32, i32* @u, align 4
; CHECK-NEXT: [[L2:%.*]] = load atomic i32, i32* @w seq_cst, align 4
; CHECK-NEXT: [[RES_1:%.*]] = sub i32 [[L1]], [[L2]]
; CHECK-NEXT: [[RES:%.*]] = add i32 [[RES_1]], [[LV]]
; CHECK-NEXT: ret i32 [[RES]]
;
%l1 = load atomic i32, i32* @w seq_cst, align 4
%lv = load volatile i32, i32* @u, align 4
%l2 = load atomic i32, i32* @w seq_cst, align 4
%res.1 = sub i32 %l1, %l2
%res = add i32 %res.1, %lv
ret i32 %res
}
define i32 @test_store(i32 %x) {
; CHECK-LABEL: @test_store(
; CHECK-NEXT: store volatile i32 [[X:%.*]], i32* @u, align 4
; CHECK-NEXT: ret i32 0
;
%l1 = load atomic i32, i32* @w unordered, align 4
store volatile i32 %x, i32* @u, align 4
%l2 = load atomic i32, i32* @w unordered, align 4
%res = sub i32 %l1, %l2
ret i32 %res
}
define i32 @test_store_with_acquire_load(i32 %x) {
; CHECK-LABEL: @test_store_with_acquire_load(
; CHECK-NEXT: [[L1:%.*]] = load atomic i32, i32* @w acquire, align 4
; CHECK-NEXT: store volatile i32 [[X:%.*]], i32* @u, align 4
; CHECK-NEXT: [[L2:%.*]] = load atomic i32, i32* @w acquire, align 4
; CHECK-NEXT: [[RES:%.*]] = sub i32 [[L1]], [[L2]]
; CHECK-NEXT: ret i32 [[RES]]
;
%l1 = load atomic i32, i32* @w acquire, align 4
store volatile i32 %x, i32* @u, align 4
%l2 = load atomic i32, i32* @w acquire, align 4
%res = sub i32 %l1, %l2
ret i32 %res
}
define i32 @test_store_with_seq_cst_load(i32 %x) {
; CHECK-LABEL: @test_store_with_seq_cst_load(
; CHECK-NEXT: [[L1:%.*]] = load atomic i32, i32* @w seq_cst, align 4
; CHECK-NEXT: store volatile i32 [[X:%.*]], i32* @u, align 4
; CHECK-NEXT: [[L2:%.*]] = load atomic i32, i32* @w seq_cst, align 4
; CHECK-NEXT: [[RES:%.*]] = sub i32 [[L1]], [[L2]]
; CHECK-NEXT: ret i32 [[RES]]
;
%l1 = load atomic i32, i32* @w seq_cst, align 4
store volatile i32 %x, i32* @u, align 4
%l2 = load atomic i32, i32* @w seq_cst, align 4
%res = sub i32 %l1, %l2
ret i32 %res
}