[llvm] Llubi docs (PR #207210)
Yingwei Zheng via llvm-commits
llvm-commits at lists.llvm.org
Thu Jul 2 08:43:45 PDT 2026
https://github.com/dtcxzyw created https://github.com/llvm/llvm-project/pull/207210
Update the docs to reflect the current status. This also addresses the post-commit review in https://github.com/llvm/llvm-project/pull/185196#discussion_r2995639990.
>From 2a4373c1be7144714287e4cff394833ebc6e8eff Mon Sep 17 00:00:00 2001
From: Yingwei Zheng <dtcxzyw2333 at gmail.com>
Date: Thu, 2 Jul 2026 23:39:55 +0800
Subject: [PATCH 1/2] [llubi][Docs] Update docs and CLI interface of llubi
---
llvm/docs/CommandGuide/llubi.rst | 26 +++++++++++++++++++
llvm/test/tools/llubi/fp_nan_preferred.ll | 2 +-
llvm/test/tools/llubi/fp_nan_quieting.ll | 2 +-
.../llubi/fp_nan_target_specific_sparc.ll | 2 +-
.../llubi/fp_nan_target_specific_wasm32.ll | 2 +-
.../fp_nan_target_specific_x86_64_linux.ll | 2 +-
llvm/test/tools/llubi/fp_nan_unchanged.ll | 2 +-
llvm/test/tools/llubi/undefmem_nondet.ll | 15 +++++++++++
llvm/test/tools/llubi/undefmem_zero.ll | 18 +++++++++++++
llvm/tools/llubi/llubi.cpp | 24 ++++++++---------
10 files changed, 77 insertions(+), 18 deletions(-)
create mode 100644 llvm/test/tools/llubi/undefmem_nondet.ll
create mode 100644 llvm/test/tools/llubi/undefmem_zero.ll
diff --git a/llvm/docs/CommandGuide/llubi.rst b/llvm/docs/CommandGuide/llubi.rst
index 55528373cffef..f68332c4af2da 100644
--- a/llvm/docs/CommandGuide/llubi.rst
+++ b/llvm/docs/CommandGuide/llubi.rst
@@ -82,6 +82,32 @@ INTERPRETER OPTIONS
* `nondet`: Each load from the same uninitialized byte yields a freshly random value. This is the default behavior.
* `zero`: Uninitialized values are treated as zero.
+.. option:: -nan-behavior=mode
+
+ Set the behavior for payload preserving behavior of floating-point NaN values.
+ The options for `mode` are:
+
+ * `nondet`: The actual behavior is randomly chosen from the modes below. This is the default behavior.
+ * `preferred`: The quiet bit is set and the payload is all-zero.
+ * `quieting`: The quiet bit is set and the payload is copied from any input operand that is a NaN.
+ * `unchanged`: The quiet bit and payload are copied from any input operand that is a NaN.
+ * `target-specific`: The quiet bit is set and the payload is picked from a known target-specific set of extra possible NaN payloads.
+
+.. option:: -deterministic
+
+ Disable interpreter-introduced non-determinism (off by default).
+ This option implies '``-undef-behavior=zero``' and '``-nan-behavior=preferred``'.
+
+.. option:: -fuse-fmuladd
+
+ Treat '``llvm.fmuladd.*``' as '``llvm.fma.*``'. It is the default behavior.
+ Otherwise, it is expended into a \* b + c.
+
+.. option:: -disable-verify
+
+ Disable the validation of the input LLVM IR. The user is responsible for the validity of inputs.
+ The verifier is executed by default.
+
EXIT STATUS
-----------
diff --git a/llvm/test/tools/llubi/fp_nan_preferred.ll b/llvm/test/tools/llubi/fp_nan_preferred.ll
index f3364e1fd22ee..49261b369a21e 100644
--- a/llvm/test/tools/llubi/fp_nan_preferred.ll
+++ b/llvm/test/tools/llubi/fp_nan_preferred.ll
@@ -1,5 +1,5 @@
; NOTE: Assertions have been autogenerated by utils/update_llubi_test_checks.py UTC_ARGS: --version 6
-; RUN: llubi --nan-preferred --verbose < %s 2>&1 | FileCheck %s
+; RUN: llubi --nan-behavior=preferred --verbose < %s 2>&1 | FileCheck %s
define void @main() {
%qnan_zero_payload = fadd double 1.0, 0x7FF8000000000000
diff --git a/llvm/test/tools/llubi/fp_nan_quieting.ll b/llvm/test/tools/llubi/fp_nan_quieting.ll
index 64e8cd67d2cd0..b3a531e04dc9c 100644
--- a/llvm/test/tools/llubi/fp_nan_quieting.ll
+++ b/llvm/test/tools/llubi/fp_nan_quieting.ll
@@ -1,5 +1,5 @@
; NOTE: Assertions have been autogenerated by utils/update_llubi_test_checks.py UTC_ARGS: --version 6
-; RUN: llubi --nan-quieting --verbose < %s 2>&1 | FileCheck %s
+; RUN: llubi --nan-behavior=quieting --verbose < %s 2>&1 | FileCheck %s
define void @main() {
%qnan_zero_payload = fadd double 1.0, 0x7FF8000000000000
diff --git a/llvm/test/tools/llubi/fp_nan_target_specific_sparc.ll b/llvm/test/tools/llubi/fp_nan_target_specific_sparc.ll
index efb42737da794..f2959bcec7ec3 100644
--- a/llvm/test/tools/llubi/fp_nan_target_specific_sparc.ll
+++ b/llvm/test/tools/llubi/fp_nan_target_specific_sparc.ll
@@ -1,5 +1,5 @@
; NOTE: Assertions have been autogenerated by utils/update_llubi_test_checks.py UTC_ARGS: --version 6
-; RUN: llubi --nan-target-specific --verbose < %s 2>&1 | FileCheck %s
+; RUN: llubi --nan-behavior=target-specific --verbose < %s 2>&1 | FileCheck %s
target triple = "sparc-unknown-linux-gnu"
diff --git a/llvm/test/tools/llubi/fp_nan_target_specific_wasm32.ll b/llvm/test/tools/llubi/fp_nan_target_specific_wasm32.ll
index b5905e023bb3e..ef53331c482f7 100644
--- a/llvm/test/tools/llubi/fp_nan_target_specific_wasm32.ll
+++ b/llvm/test/tools/llubi/fp_nan_target_specific_wasm32.ll
@@ -1,5 +1,5 @@
; NOTE: Assertions have been autogenerated by utils/update_llubi_test_checks.py UTC_ARGS: --version 6
-; RUN: llubi --nan-target-specific --verbose < %s 2>&1 | FileCheck %s
+; RUN: llubi --nan-behavior=target-specific --verbose < %s 2>&1 | FileCheck %s
target triple = "wasm32-unknown-unknown"
diff --git a/llvm/test/tools/llubi/fp_nan_target_specific_x86_64_linux.ll b/llvm/test/tools/llubi/fp_nan_target_specific_x86_64_linux.ll
index 39a754c6f247b..3540ddb06fe9b 100644
--- a/llvm/test/tools/llubi/fp_nan_target_specific_x86_64_linux.ll
+++ b/llvm/test/tools/llubi/fp_nan_target_specific_x86_64_linux.ll
@@ -1,5 +1,5 @@
; NOTE: Assertions have been autogenerated by utils/update_llubi_test_checks.py UTC_ARGS: --version 6
-; RUN: llubi --nan-target-specific --verbose < %s 2>&1 | FileCheck %s
+; RUN: llubi --nan-behavior=target-specific --verbose < %s 2>&1 | FileCheck %s
target triple = "x86_64-unknown-linux-gnu"
diff --git a/llvm/test/tools/llubi/fp_nan_unchanged.ll b/llvm/test/tools/llubi/fp_nan_unchanged.ll
index 260e878f9f600..b4178a85e37fb 100644
--- a/llvm/test/tools/llubi/fp_nan_unchanged.ll
+++ b/llvm/test/tools/llubi/fp_nan_unchanged.ll
@@ -1,5 +1,5 @@
; NOTE: Assertions have been autogenerated by utils/update_llubi_test_checks.py UTC_ARGS: --version 6
-; RUN: llubi --nan-unchanged --verbose < %s 2>&1 | FileCheck %s
+; RUN: llubi --nan-behavior=unchanged --verbose < %s 2>&1 | FileCheck %s
define void @main() {
%qnan_zero_payload = fadd double 1.0, 0x7FF8000000000000
diff --git a/llvm/test/tools/llubi/undefmem_nondet.ll b/llvm/test/tools/llubi/undefmem_nondet.ll
new file mode 100644
index 0000000000000..dc47bda0b97e8
--- /dev/null
+++ b/llvm/test/tools/llubi/undefmem_nondet.ll
@@ -0,0 +1,15 @@
+; NOTE: Assertions have been autogenerated by utils/update_llubi_test_checks.py UTC_ARGS: --version 6
+; RUN: llubi --undef-behavior=nondet --verbose < %s 2>&1 | FileCheck %s
+
+define void @main() {
+ %alloc = alloca i32
+ %load_undef1 = load i32, ptr %alloc
+ %load_undef2 = load i32, ptr %alloc
+ ret void
+}
+; CHECK: Entering function: main
+; CHECK-NEXT: %alloc = alloca i32, align 4 => ptr 0x8 [alloc]
+; CHECK-NEXT: %load_undef1 = load i32, ptr %alloc, align 4 => i32 -289830082
+; CHECK-NEXT: %load_undef2 = load i32, ptr %alloc, align 4 => i32 -399511892
+; CHECK-NEXT: ret void
+; CHECK-NEXT: Exiting function: main
diff --git a/llvm/test/tools/llubi/undefmem_zero.ll b/llvm/test/tools/llubi/undefmem_zero.ll
new file mode 100644
index 0000000000000..7369e4034ea1b
--- /dev/null
+++ b/llvm/test/tools/llubi/undefmem_zero.ll
@@ -0,0 +1,18 @@
+; NOTE: Assertions have been autogenerated by utils/update_llubi_test_checks.py UTC_ARGS: --version 6
+; RUN: not llubi --undef-behavior=zero --verbose < %s 2>&1 | FileCheck %s
+
+define void @main() {
+ %alloc = alloca i32
+ %load_undef1 = load i32, ptr %alloc
+ %load_undef2 = load i32, ptr %alloc
+ %load_noundef = load i32, ptr %alloc, !noundef !{}
+ ret void
+}
+; CHECK: Entering function: main
+; CHECK-NEXT: %alloc = alloca i32, align 4 => ptr 0x8 [alloc]
+; CHECK-NEXT: %load_undef1 = load i32, ptr %alloc, align 4 => i32 0
+; CHECK-NEXT: %load_undef2 = load i32, ptr %alloc, align 4 => i32 0
+; CHECK-NEXT: Stacktrace:
+; CHECK-NEXT: #0 %load_noundef = load i32, ptr %alloc, align 4, !noundef !0 at @main <stdin>:8
+; CHECK-NEXT: Immediate UB detected: The value loaded contains undefined bits.
+; CHECK-NEXT: error: Execution of function 'main' failed.
diff --git a/llvm/tools/llubi/llubi.cpp b/llvm/tools/llubi/llubi.cpp
index fd6d0fa807761..fd0e8e8f55ace 100644
--- a/llvm/tools/llubi/llubi.cpp
+++ b/llvm/tools/llubi/llubi.cpp
@@ -94,30 +94,30 @@ static cl::opt<bool> NoVerify("disable-verify",
cl::init(false), cl::cat(InterpreterCategory));
cl::opt<ubi::UndefValueBehavior> UndefBehavior(
- "", cl::desc("Choose undef value behavior:"),
- cl::values(clEnumVal(ubi::UndefValueBehavior::NonDeterministic,
- "Each load of an uninitialized byte yields a freshly "
- "random value."),
- clEnumVal(ubi::UndefValueBehavior::Zero,
- "All uses of an uninitialized byte yield zero.")));
+ "undef-behavior", cl::desc("Choose undef value behavior:"),
+ cl::values(clEnumValN(ubi::UndefValueBehavior::NonDeterministic, "nondet",
+ "Each load of an uninitialized byte yields a freshly "
+ "random value."),
+ clEnumValN(ubi::UndefValueBehavior::Zero, "zero",
+ "All uses of an uninitialized byte yield zero.")));
cl::opt<ubi::NaNPropagationBehavior> NaNPropagationBehavior(
- "", cl::desc("Choose NaN propagation behavior:"),
+ "nan-behavior", cl::desc("Choose NaN propagation behavior:"),
cl::values(
- clEnumValN(ubi::NaNPropagationBehavior::NonDeterministic, "nan-nodet",
+ clEnumValN(ubi::NaNPropagationBehavior::NonDeterministic, "nondet",
"Non-deterministically choose from valid NaN results as "
"specified by language reference."),
- clEnumValN(ubi::NaNPropagationBehavior::PreferredNaN, "nan-preferred",
+ clEnumValN(ubi::NaNPropagationBehavior::PreferredNaN, "preferred",
"The quiet bit is set and the payload is all-zero."),
clEnumValN(
- ubi::NaNPropagationBehavior::QuietingNaN, "nan-quieting",
+ ubi::NaNPropagationBehavior::QuietingNaN, "quieting",
"The quiet bit is set and the payload is copied from any input"
"operand that is a NaN."),
- clEnumValN(ubi::NaNPropagationBehavior::UnchangedNaN, "nan-unchanged",
+ clEnumValN(ubi::NaNPropagationBehavior::UnchangedNaN, "unchanged",
"The quiet bit and payload are copied from any input operand"
"that is a NaN"),
clEnumValN(ubi::NaNPropagationBehavior::TargetSpecificNaN,
- "nan-target-specific",
+ "target-specific",
"The quiet bit is set and the payload is picked from a "
"known target-specific set of \"extra\" possible NaN "
"payloads.")),
>From 587ad15a976f166555b36099091f59e2739ba171 Mon Sep 17 00:00:00 2001
From: Yingwei Zheng <dtcxzyw2333 at gmail.com>
Date: Thu, 2 Jul 2026 23:42:53 +0800
Subject: [PATCH 2/2] [Docs] Fix typo
---
llvm/docs/CommandGuide/llubi.rst | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/llvm/docs/CommandGuide/llubi.rst b/llvm/docs/CommandGuide/llubi.rst
index f68332c4af2da..0e8ed54592e5d 100644
--- a/llvm/docs/CommandGuide/llubi.rst
+++ b/llvm/docs/CommandGuide/llubi.rst
@@ -101,7 +101,7 @@ INTERPRETER OPTIONS
.. option:: -fuse-fmuladd
Treat '``llvm.fmuladd.*``' as '``llvm.fma.*``'. It is the default behavior.
- Otherwise, it is expended into a \* b + c.
+ Otherwise, it is expanded into a \* b + c.
.. option:: -disable-verify
More information about the llvm-commits
mailing list