From 60fe437be65023a58f08050f6a1439ee5ad3352c Mon Sep 17 00:00:00 2001 From: John Regehr Date: Thu, 15 Jan 2026 15:18:26 -0700 Subject: [PATCH 1/3] initial commit --- llvm_util/llvm2alive.cpp | 35 +++++++++++++++++-- .../noundef-intrinsic-argument.srctgt.ll | 11 ++++++ 2 files changed, 44 insertions(+), 2 deletions(-) create mode 100644 tests/alive-tv/attrs/noundef-intrinsic-argument.srctgt.ll diff --git a/llvm_util/llvm2alive.cpp b/llvm_util/llvm2alive.cpp index d0ae6ba68..c65d088bf 100644 --- a/llvm_util/llvm2alive.cpp +++ b/llvm_util/llvm2alive.cpp @@ -211,6 +211,16 @@ class llvm2alive_ : public llvm::InstVisitor> { return make_unique(*make_intconst(0, 1), Assume::AndNonPoison); } + void addNoundefAssumes(const llvm::CallBase &i, + std::initializer_list args) { + unsigned idx = 0; + for (auto *arg : args) { + if (i.paramHasAttr(idx, llvm::Attribute::NoUndef)) + BB->addInstr(make_unique(*arg, Assume::WellDefined)); + ++idx; + } + } + public: llvm2alive_(llvm::Function &f, const llvm::TargetLibraryInfo &TLI, bool IsSrc, const vector &gvsInSrc) @@ -807,6 +817,7 @@ class llvm2alive_ : public llvm::InstVisitor> { } } PARSE_UNOP(); + addNoundefAssumes(i, {val}); return make_unique(*val, Assume::AndNonPoison); } case llvm::Intrinsic::sadd_with_overflow: @@ -831,6 +842,7 @@ class llvm2alive_ : public llvm::InstVisitor> { case llvm::Intrinsic::ucmp: case llvm::Intrinsic::scmp: { PARSE_BINOP(); + addNoundefAssumes(i, {a, b}); BinOp::Op op; switch (i.getIntrinsicID()) { case llvm::Intrinsic::sadd_with_overflow: op=BinOp::SAdd_Overflow; break; @@ -867,6 +879,7 @@ class llvm2alive_ : public llvm::InstVisitor> { case llvm::Intrinsic::expect_with_probability: case llvm::Intrinsic::is_constant: { PARSE_UNOP(); + addNoundefAssumes(i, {val}); UnaryOp::Op op; switch (i.getIntrinsicID()) { case llvm::Intrinsic::bitreverse: op = UnaryOp::BitReverse; break; @@ -892,6 +905,7 @@ class llvm2alive_ : public llvm::InstVisitor> { case llvm::Intrinsic::vector_reduce_umax: case llvm::Intrinsic::vector_reduce_umin: { PARSE_UNOP(); + addNoundefAssumes(i, {val}); UnaryReductionOp::Op op; switch (i.getIntrinsicID()) { case llvm::Intrinsic::vector_reduce_add: op = UnaryReductionOp::Add; break; @@ -912,8 +926,9 @@ class llvm2alive_ : public llvm::InstVisitor> { case llvm::Intrinsic::vector_reduce_fmax: case llvm::Intrinsic::vector_reduce_fminimum: case llvm::Intrinsic::vector_reduce_fmaximum: { - PARSE_UNOP(); - FpUnaryReductionOp::Op op; + PARSE_UNOP(); + addNoundefAssumes(i, {val}); + FpUnaryReductionOp::Op op; switch (i.getIntrinsicID()) { case llvm::Intrinsic::vector_reduce_fmin: op = FpUnaryReductionOp::FMin; break; case llvm::Intrinsic::vector_reduce_fmax: op = FpUnaryReductionOp::FMax; break; @@ -935,6 +950,7 @@ class llvm2alive_ : public llvm::InstVisitor> { case llvm::Intrinsic::objectsize: { PARSE_TRIOP(); + addNoundefAssumes(i, {a, b, c}); TernaryOp::Op op; switch (i.getIntrinsicID()) { case llvm::Intrinsic::fshl: op = TernaryOp::FShl; break; @@ -955,6 +971,7 @@ class llvm2alive_ : public llvm::InstVisitor> { case llvm::Intrinsic::experimental_constrained_fmuladd: { PARSE_TRIOP(); + addNoundefAssumes(i, {a, b, c}); FpTernaryOp::Op op; switch (i.getIntrinsicID()) { case llvm::Intrinsic::fma: @@ -985,6 +1002,7 @@ class llvm2alive_ : public llvm::InstVisitor> { case llvm::Intrinsic::experimental_constrained_maximum: { PARSE_BINOP(); + addNoundefAssumes(i, {a, b}); FpBinOp::Op op; switch (i.getIntrinsicID()) { case llvm::Intrinsic::copysign: op = FpBinOp::CopySign; break; @@ -1028,6 +1046,7 @@ class llvm2alive_ : public llvm::InstVisitor> { case llvm::Intrinsic::experimental_constrained_trunc: { PARSE_UNOP(); + addNoundefAssumes(i, {val}); FpUnaryOp::Op op; switch (i.getIntrinsicID()) { case llvm::Intrinsic::canonicalize: op = FpUnaryOp::Canonicalize; break; @@ -1057,6 +1076,7 @@ class llvm2alive_ : public llvm::InstVisitor> { case llvm::Intrinsic::frexp: { PARSE_UNOP(); + addNoundefAssumes(i, {val}); FpUnaryOpVerticalZip::Op op; switch (i.getIntrinsicID()) { case llvm::Intrinsic::frexp: op = FpUnaryOpVerticalZip::FrExp; break; @@ -1084,6 +1104,7 @@ class llvm2alive_ : public llvm::InstVisitor> { case llvm::Intrinsic::fptosi_sat: { PARSE_UNOP(); + addNoundefAssumes(i, {val}); FpConversionOp::Op op; switch (i.getIntrinsicID()) { case llvm::Intrinsic::experimental_constrained_sitofp: op = FpConversionOp::SIntToFP; break; @@ -1114,6 +1135,7 @@ class llvm2alive_ : public llvm::InstVisitor> { case llvm::Intrinsic::experimental_constrained_fcmps: { PARSE_BINOP(); + addNoundefAssumes(i, {a, b}); auto *fcmp = cast(&i); auto cond = parse_fcmp_cond(fcmp->getPredicate()); ret = make_unique(*ty, value_name(i), cond, *a, *b, FastMathFlags(), @@ -1123,6 +1145,7 @@ class llvm2alive_ : public llvm::InstVisitor> { case llvm::Intrinsic::is_fpclass: { PARSE_BINOP(); + addNoundefAssumes(i, {a, b}); TestOp::Op op; switch (i.getIntrinsicID()) { case llvm::Intrinsic::is_fpclass: op = TestOp::Is_FPClass; break; @@ -1135,6 +1158,7 @@ class llvm2alive_ : public llvm::InstVisitor> { case llvm::Intrinsic::lifetime_end: { PARSE_UNOP(); + addNoundefAssumes(i, {val}); if (isa(i.getOperand(1))) return NOP(i); if (i.getIntrinsicID() == llvm::Intrinsic::lifetime_end) @@ -1166,6 +1190,7 @@ class llvm2alive_ : public llvm::InstVisitor> { case llvm::Intrinsic::ptrmask: { PARSE_BINOP(); + addNoundefAssumes(i, {a, b}); ret = make_unique(*ty, value_name(i), *a, *b); break; } @@ -1187,14 +1212,17 @@ class llvm2alive_ : public llvm::InstVisitor> { } case llvm::Intrinsic::vastart: { PARSE_UNOP(); + addNoundefAssumes(i, {val}); return make_unique(*val); } case llvm::Intrinsic::vaend: { PARSE_UNOP(); + addNoundefAssumes(i, {val}); return make_unique(*val); } case llvm::Intrinsic::vacopy: { PARSE_BINOP(); + addNoundefAssumes(i, {a, b}); return make_unique(*a, *b); } @@ -1216,6 +1244,7 @@ class llvm2alive_ : public llvm::InstVisitor> { #undef PROCESS { PARSE_BINOP(); + addNoundefAssumes(i, {a, b}); X86IntrinBinOp::Op op; switch (i.getIntrinsicID()) { #define PROCESS(NAME, A, B, C, D, E, F) \ @@ -1235,6 +1264,7 @@ class llvm2alive_ : public llvm::InstVisitor> { #undef PROCESS { PARSE_TRIOP(); + addNoundefAssumes(i, {a, b, c}); X86IntrinTerOp::Op op; switch (i.getIntrinsicID()) { #define PROCESS(NAME, A, B, C, D, E, F, G, H) \ @@ -1254,6 +1284,7 @@ class llvm2alive_ : public llvm::InstVisitor> { #undef PROCESS { PARSE_QUADOP(); + addNoundefAssumes(i, {a, b, c, d}); X86IntrinQuadOp::Op op; switch (i.getIntrinsicID()) { #define PROCESS(NAME) \ diff --git a/tests/alive-tv/attrs/noundef-intrinsic-argument.srctgt.ll b/tests/alive-tv/attrs/noundef-intrinsic-argument.srctgt.ll new file mode 100644 index 000000000..1cc342600 --- /dev/null +++ b/tests/alive-tv/attrs/noundef-intrinsic-argument.srctgt.ll @@ -0,0 +1,11 @@ +define float @src(float %a) { + %fabs = call float @llvm.fabs.f32(float noundef %a) + ret float %fabs +} + +define noundef float @tgt(float %a) { + %fabs = call float @llvm.fabs.f32(float noundef %a) + ret float %fabs +} + +declare float @llvm.fabs.f32(float) From 49bc70d19d34a40e8f1a646a25e2755c7f2c1060 Mon Sep 17 00:00:00 2001 From: John Regehr Date: Thu, 15 Jan 2026 20:52:10 -0700 Subject: [PATCH 2/3] pass reference instead of object --- llvm_util/llvm2alive.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/llvm_util/llvm2alive.cpp b/llvm_util/llvm2alive.cpp index c65d088bf..70ae241f5 100644 --- a/llvm_util/llvm2alive.cpp +++ b/llvm_util/llvm2alive.cpp @@ -212,7 +212,7 @@ class llvm2alive_ : public llvm::InstVisitor> { } void addNoundefAssumes(const llvm::CallBase &i, - std::initializer_list args) { + const std::initializer_list &args) { unsigned idx = 0; for (auto *arg : args) { if (i.paramHasAttr(idx, llvm::Attribute::NoUndef)) From 48538ff3bdbbc7e0bfb71ccde203119e44ba40bb Mon Sep 17 00:00:00 2001 From: Nuno Lopes Date: Fri, 16 Jan 2026 09:49:38 +0000 Subject: [PATCH 3/3] Remove addNoundefAssumes call from llvm2alive Removed the call to addNoundefAssumes in the handling of certain LLVM intrinsics. --- llvm_util/llvm2alive.cpp | 1 - 1 file changed, 1 deletion(-) diff --git a/llvm_util/llvm2alive.cpp b/llvm_util/llvm2alive.cpp index 70ae241f5..62d35e3cd 100644 --- a/llvm_util/llvm2alive.cpp +++ b/llvm_util/llvm2alive.cpp @@ -817,7 +817,6 @@ class llvm2alive_ : public llvm::InstVisitor> { } } PARSE_UNOP(); - addNoundefAssumes(i, {val}); return make_unique(*val, Assume::AndNonPoison); } case llvm::Intrinsic::sadd_with_overflow: