From 7bdb485e1841ceb8421a1d9e62cf120b9b77f527 Mon Sep 17 00:00:00 2001 From: Ulrich Weigand Date: Tue, 25 Oct 2016 15:39:15 +0000 Subject: [PATCH] [SystemZ] Do not use LOC(G) for volatile loads It is not safe to use LOAD ON CONDITION to implement access to a memory location marked "volatile", since the architecture leaves it unspecified whether or not an access happens if the condition is false. The current code already appears to care about that: def LOC : CondUnaryRSY<"loc", 0xEBF2, nonvolatile_load, GR32, 4>; Unfortunately, that "nonvolatile_load" operator is simply ignored by the CondUnaryRSY class, and there was no test to catch it. llvm-svn: 285077 --- llvm/lib/Target/SystemZ/SystemZInstrFormats.td | 2 +- llvm/test/CodeGen/SystemZ/cond-load-01.ll | 14 ++++++++++++++ llvm/test/CodeGen/SystemZ/cond-load-02.ll | 14 ++++++++++++++ 3 files changed, 29 insertions(+), 1 deletion(-) diff --git a/llvm/lib/Target/SystemZ/SystemZInstrFormats.td b/llvm/lib/Target/SystemZ/SystemZInstrFormats.td index 68ed6ae..8d283a0 100644 --- a/llvm/lib/Target/SystemZ/SystemZInstrFormats.td +++ b/llvm/lib/Target/SystemZ/SystemZInstrFormats.td @@ -1665,7 +1665,7 @@ class CondUnaryRSY opcode, (ins cls:$R1src, mode:$BD2, cond4:$valid, cond4:$R3), mnemonic#"$R3\t$R1, $BD2", [(set cls:$R1, - (z_select_ccmask (load bdaddr20only:$BD2), cls:$R1src, + (z_select_ccmask (operator bdaddr20only:$BD2), cls:$R1src, cond4:$valid, cond4:$R3))]>, Requires<[FeatureLoadStoreOnCond]> { let Constraints = "$R1 = $R1src"; diff --git a/llvm/test/CodeGen/SystemZ/cond-load-01.ll b/llvm/test/CodeGen/SystemZ/cond-load-01.ll index 97d4027..d10551f 100644 --- a/llvm/test/CodeGen/SystemZ/cond-load-01.ll +++ b/llvm/test/CodeGen/SystemZ/cond-load-01.ll @@ -128,3 +128,17 @@ exit: %res = phi i32 [ %easy, %entry ], [ %other, %load ] ret i32 %res } + +; Test that volatile loads do not use LOC, since if the condition is false, +; it is unspecified whether or not the load happens. LOCR is fine though. +define i32 @f10(i32 %easy, i32 *%ptr, i32 %limit) { +; CHECK-LABEL: f10: +; CHECK: l {{%r[0-9]*}}, 0(%r3) +; CHECK: locr +; CHECK: br %r14 + %cond = icmp ult i32 %limit, 42 + %other = load volatile i32, i32 *%ptr + %res = select i1 %cond, i32 %easy, i32 %other + ret i32 %res +} + diff --git a/llvm/test/CodeGen/SystemZ/cond-load-02.ll b/llvm/test/CodeGen/SystemZ/cond-load-02.ll index d0fe65e..c40b2cc 100644 --- a/llvm/test/CodeGen/SystemZ/cond-load-02.ll +++ b/llvm/test/CodeGen/SystemZ/cond-load-02.ll @@ -128,3 +128,17 @@ exit: %res = phi i64 [ %easy, %entry ], [ %other, %load ] ret i64 %res } + +; Test that volatile loads do not use LOCG, since if the condition is false, +; it is unspecified whether or not the load happens. LOCGR is fine though. +define i64 @f10(i64 %easy, i64 *%ptr, i64 %limit) { +; CHECK-LABEL: f10: +; CHECK: lg {{%r[0-9]*}}, 0(%r3) +; CHECK: locgr +; CHECK: br %r14 + %cond = icmp ult i64 %limit, 42 + %other = load volatile i64, i64 *%ptr + %res = select i1 %cond, i64 %easy, i64 %other + ret i64 %res +} + -- 2.7.4