Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Optionally encode floating point operations as uninterpreted functions #1057

Closed
wants to merge 31 commits into from
Closed
Show file tree
Hide file tree
Changes from 24 commits
Commits
Show all changes
31 commits
Select commit Hold shift + click to select a range
e39513b
Add getOpName and getCondName
can-leh-emmtrix Jun 17, 2024
263f62c
Add --uf-float command line option
can-leh-emmtrix Jun 17, 2024
d67f7aa
Map floating point operations to uninterpreted functions
can-leh-emmtrix Jun 17, 2024
e5661c2
Handle poison values in FpBinOp
can-leh-emmtrix Jun 18, 2024
4dd1cab
Encode commutativity
can-leh-emmtrix Jun 18, 2024
14d14d4
Handle poison
can-leh-emmtrix Jun 18, 2024
d2fb021
Fix return type for FCmp
can-leh-emmtrix Jun 18, 2024
233f6b5
Use qualified call to std::move
can-leh-emmtrix Jun 18, 2024
4149c54
Add tests
can-leh-emmtrix Jun 18, 2024
aaf6b36
Use scalar type as suffix for UF
can-leh-emmtrix Jun 19, 2024
9c2384d
Encode all fcmp conditions using oeq, ueq, olt, ult, ord
can-leh-emmtrix Jun 19, 2024
35247ea
Fix poison for fast math
can-leh-emmtrix Jun 19, 2024
0ccb8f4
Add more tests
can-leh-emmtrix Jul 1, 2024
736ff33
Rename FpMappingMode to FpEncodingMode
can-leh-emmtrix Jul 1, 2024
0a4c47c
Refactor
can-leh-emmtrix Jul 2, 2024
69178f8
Fix FpConversionOp for vectors
can-leh-emmtrix Jul 15, 2024
6c80504
Fix code style
can-leh-emmtrix Jul 15, 2024
aba1f4a
Merge branch 'master' into uf-float
can-leh-emmtrix Jul 16, 2024
e724a88
Merge branch 'master' into uf-float
can-leh-emmtrix Aug 5, 2024
9c21f56
Split long lines
can-leh-emmtrix Aug 5, 2024
055172e
Unindent existing code
can-leh-emmtrix Aug 5, 2024
4b5ffe4
Smaller diff
can-leh-emmtrix Aug 5, 2024
fa3cf88
Reference paper in comment
can-leh-emmtrix Aug 5, 2024
8eef61c
Split long lines
can-leh-emmtrix Aug 5, 2024
35f65ad
Fix formatting
can-leh-emmtrix Aug 6, 2024
123ee99
Use doesApproximation correctly
can-leh-emmtrix Aug 6, 2024
0685b96
Remove unused FCmp::getCondName
can-leh-emmtrix Aug 6, 2024
51e4cc5
Refactor FpConversionOp
can-leh-emmtrix Aug 6, 2024
c397911
Move variable declarations to same line as definitions
can-leh-emmtrix Aug 6, 2024
b8d2f83
Fix formatting
can-leh-emmtrix Aug 7, 2024
4584dc8
Merge branch 'master' into uf-float
can-leh-emmtrix Sep 24, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
356 changes: 276 additions & 80 deletions ir/instr.cpp

Large diffs are not rendered by default.

7 changes: 7 additions & 0 deletions ir/instr.h
Original file line number Diff line number Diff line change
Expand Up @@ -89,6 +89,8 @@ class FpBinOp final : public Instr {
bool propagatesPoison() const override;
bool hasSideEffects() const override;
void rauw(const Value &what, Value &with) override;
const char* getOpName() const;
bool isCommutative() const;
void print(std::ostream &os) const override;
StateValue toSMT(State &s) const override;
smt::expr getTypeConstraints(const Function &f) const override;
Expand Down Expand Up @@ -155,6 +157,7 @@ class FpUnaryOp final : public Instr {
bool propagatesPoison() const override;
bool hasSideEffects() const override;
void rauw(const Value &what, Value &with) override;
const char* getOpName() const;
void print(std::ostream &os) const override;
StateValue toSMT(State &s) const override;
smt::expr getTypeConstraints(const Function &f) const override;
Expand Down Expand Up @@ -244,6 +247,7 @@ class FpTernaryOp final : public Instr {
bool propagatesPoison() const override;
bool hasSideEffects() const override;
void rauw(const Value &what, Value &with) override;
const char* getOpName() const;
void print(std::ostream &os) const override;
StateValue toSMT(State &s) const override;
smt::expr getTypeConstraints(const Function &f) const override;
Expand All @@ -269,6 +273,7 @@ class TestOp final : public Instr {
bool propagatesPoison() const override;
bool hasSideEffects() const override;
void rauw(const Value &what, Value &with) override;
const char* getOpName() const;
void print(std::ostream &os) const override;
StateValue toSMT(State &s) const override;
smt::expr getTypeConstraints(const Function &f) const override;
Expand Down Expand Up @@ -333,6 +338,7 @@ class FpConversionOp final : public Instr {
bool propagatesPoison() const override;
bool hasSideEffects() const override;
void rauw(const Value &what, Value &with) override;
const char* getOpName() const;
void print(std::ostream &os) const override;
StateValue toSMT(State &s) const override;
smt::expr getTypeConstraints(const Function &f) const override;
Expand Down Expand Up @@ -474,6 +480,7 @@ class FCmp final : public Instr {
bool propagatesPoison() const override;
bool hasSideEffects() const override;
void rauw(const Value &what, Value &with) override;
const char* getCondName() const;
void print(std::ostream &os) const override;
StateValue toSMT(State &s) const override;
smt::expr getTypeConstraints(const Function &f) const override;
Expand Down
6 changes: 6 additions & 0 deletions llvm_util/cmd_args_def.h
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,12 @@ if ((config::disallow_ub_exploitation = opt_disallow_ub_exploitation)) {
config::disable_poison_input = true;
}

if (opt_uf_float) {
config::fp_encoding_mode = config::FpEncodingMode::UninterpretedFunctions;
} else {
config::fp_encoding_mode = config::FpEncodingMode::FloatingPoint;
}

func_names.insert(opt_funcs.begin(), opt_funcs.end());

if (!report_dir_created && !opt_report_dir.empty()) {
Expand Down
5 changes: 5 additions & 0 deletions llvm_util/cmd_args_list.h
Original file line number Diff line number Diff line change
Expand Up @@ -185,4 +185,9 @@ llvm::cl::opt<bool> opt_disallow_ub_exploitation(
llvm::cl::desc("Disallow UB exploitation by optimizations (default=allow)"),
llvm::cl::init(false), llvm::cl::cat(alive_cmdargs));

llvm::cl::opt<bool> opt_uf_float(
LLVM_ARGS_PREFIX "uf-float",
llvm::cl::desc("Approximate floating point operations as uninterpreted functions"),
llvm::cl::init(false), llvm::cl::cat(alive_cmdargs));

}
14 changes: 14 additions & 0 deletions tests/alive-tv/uf-float/add-assoc-fail.srctgt.ll
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
; TEST-ARGS: --uf-float
; ERROR: Couldn't prove the correctness of the transformation

define float @src(float noundef %x, float noundef %y, float noundef %z) {
%a = fadd float %x, %y
%b = fadd float %a, %z
ret float %b
}

define float @tgt(float noundef %x, float noundef %y, float noundef %z) {
%a = fadd float %y, %z
%b = fadd float %x, %a
ret float %b
}
11 changes: 11 additions & 0 deletions tests/alive-tv/uf-float/add-comm-double.srctgt.ll
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
; TEST-ARGS: --uf-float

define double @src(double noundef %x, double noundef %y) {
%sum = fadd double %x, %y
ret double %sum
}

define double @tgt(double noundef %x, double noundef %y) {
%sum = fadd double %y, %x
ret double %sum
}
11 changes: 11 additions & 0 deletions tests/alive-tv/uf-float/add-comm-fp128.srctgt.ll
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
; TEST-ARGS: --uf-float

define fp128 @src(fp128 noundef %x, fp128 noundef %y) {
%sum = fadd fp128 %x, %y
ret fp128 %sum
}

define fp128 @tgt(fp128 noundef %x, fp128 noundef %y) {
%sum = fadd fp128 %y, %x
ret fp128 %sum
}
11 changes: 11 additions & 0 deletions tests/alive-tv/uf-float/add-comm-half.srctgt.ll
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
; TEST-ARGS: --uf-float

define half @src(half noundef %x, half noundef %y) {
%sum = fadd half %x, %y
ret half %sum
}

define half @tgt(half noundef %x, half noundef %y) {
%sum = fadd half %y, %x
ret half %sum
}
11 changes: 11 additions & 0 deletions tests/alive-tv/uf-float/add-comm-ninf.srctgt.ll
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
; TEST-ARGS: --uf-float

define float @src(float noundef %x, float noundef %y) {
%sum = fadd ninf float %x, %y
ret float %sum
}

define float @tgt(float noundef %x, float noundef %y) {
%sum = fadd ninf float %y, %x
ret float %sum
}
11 changes: 11 additions & 0 deletions tests/alive-tv/uf-float/add-comm-nnan.srctgt.ll
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
; TEST-ARGS: --uf-float

define float @src(float noundef %x, float noundef %y) {
%sum = fadd nnan float %x, %y
ret float %sum
}

define float @tgt(float noundef %x, float noundef %y) {
%sum = fadd nnan float %y, %x
ret float %sum
}
11 changes: 11 additions & 0 deletions tests/alive-tv/uf-float/add-comm.srctgt.ll
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
; TEST-ARGS: --uf-float

define float @src(float noundef %x, float noundef %y) {
%sum = fadd float %x, %y
ret float %sum
}

define float @tgt(float noundef %x, float noundef %y) {
%sum = fadd float %y, %x
ret float %sum
}
11 changes: 11 additions & 0 deletions tests/alive-tv/uf-float/cmp-eq-comm.srctgt.ll
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
; TEST-ARGS: --uf-float

define i1 @src(float noundef %x, float noundef %y) {
%cmp = fcmp oeq float %x, %y
ret i1 %cmp
}

define i1 @tgt(float noundef %x, float noundef %y) {
%cmp = fcmp oeq float %y, %x
ret i1 %cmp
}
12 changes: 12 additions & 0 deletions tests/alive-tv/uf-float/cmp-eq-ne.srctgt.ll
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
; TEST-ARGS: --uf-float

define i1 @src(float noundef %x, float noundef %y) {
%cmp = fcmp oeq float %x, %y
ret i1 %cmp
}

define i1 @tgt(float noundef %x, float noundef %y) {
%cmp = fcmp une float %x, %y
%notcmp = xor i1 %cmp, 1
ret i1 %notcmp
}
11 changes: 11 additions & 0 deletions tests/alive-tv/uf-float/cmp-lt-gt.srctgt.ll
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
; TEST-ARGS: --uf-float

define i1 @src(float noundef %x, float noundef %y) {
%cmp = fcmp olt float %x, %y
ret i1 %cmp
}

define i1 @tgt(float noundef %x, float noundef %y) {
%cmp = fcmp ogt float %y, %x
ret i1 %cmp
}
12 changes: 12 additions & 0 deletions tests/alive-tv/uf-float/cmp-lt-le.srctgt.ll
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
; TEST-ARGS: --uf-float

define i1 @src(float noundef %x, float noundef %y) {
%cmp = fcmp olt float %x, %y
ret i1 %cmp
}

define i1 @tgt(float noundef %x, float noundef %y) {
%cmp = fcmp ule float %y, %x
%notcmp = xor i1 %cmp, 1
ret i1 %notcmp
}
12 changes: 12 additions & 0 deletions tests/alive-tv/uf-float/cmp-olt-ult-fail.srctgt.ll
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
; TEST-ARGS: --uf-float
; ERROR: Couldn't prove the correctness of the transformation

define i1 @src(float noundef %x, float noundef %y) {
%cmp = fcmp olt float %x, %y
ret i1 %cmp
}

define i1 @tgt(float noundef %x, float noundef %y) {
%cmp = fcmp ult float %x, %y
ret i1 %cmp
}
12 changes: 12 additions & 0 deletions tests/alive-tv/uf-float/cmp-ord-uno.srctgt.ll
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
; TEST-ARGS: --uf-float

define i1 @src(float noundef %x, float noundef %y) {
%cmp = fcmp ord float %x, %y
%notcmp = xor i1 %cmp, 1
ret i1 %notcmp
}

define i1 @tgt(float noundef %x, float noundef %y) {
%cmp = fcmp uno float %y, %x
ret i1 %cmp
}
13 changes: 13 additions & 0 deletions tests/alive-tv/uf-float/load-bitcast.srctgt.ll
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
; TEST-ARGS: --uf-float

define i32 @src(float noundef %x) {
%a = bitcast float %x to i32
ret i32 %a
}

define i32 @tgt(float noundef %x) {
%a = alloca float
store float %x, ptr %a
%b = load i32, ptr %a
ret i32 %b
}
12 changes: 12 additions & 0 deletions tests/alive-tv/uf-float/load-store.srctgt.ll
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
; TEST-ARGS: --uf-float

define float @src(float noundef %x) {
ret float %x
}

define float @tgt(float noundef %x) {
%a = alloca float
store float %x, ptr %a
%b = load float, ptr %a
ret float %b
}
17 changes: 17 additions & 0 deletions tests/alive-tv/uf-float/select.srctgt.ll
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
; TEST-ARGS: --uf-float

define float @src(float noundef %x, float noundef %y) {
%cmp = fcmp olt float %x, %y
%a = fsub float %y, %x
%b = fsub float %x, %y
%c = select i1 %cmp, float %a, float %b
ret float %c
}

define float @tgt(float noundef %x, float noundef %y) {
%cmp = fcmp olt float %x, %y
%min = select i1 %cmp, float %x, float %y
%max = select i1 %cmp, float %y, float %x
%res = fsub float %max, %min
ret float %res
}
14 changes: 14 additions & 0 deletions tests/alive-tv/uf-float/vector-binop.srctgt.ll
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
; TEST-ARGS: --uf-float

define float @src(float noundef %x, float noundef %y) {
%sum = fadd float %x, %y
ret float %sum
}

define float @tgt(float noundef %x, float noundef %y) {
%vec1 = insertelement <2 x float> poison, float %x, i32 0
%vec2 = insertelement <2 x float> poison, float %y, i32 0
%vec3 = fadd <2 x float> %vec1, %vec2
%sum = extractelement <2 x float> %vec3, i32 0
ret float %sum
}
14 changes: 14 additions & 0 deletions tests/alive-tv/uf-float/vector-cmp.srctgt.ll
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
; TEST-ARGS: --uf-float

define i1 @src(float noundef %x, float noundef %y) {
%res = fcmp olt float %x, %y
ret i1 %res
}

define i1 @tgt(float noundef %x, float noundef %y) {
%vec1 = insertelement <2 x float> poison, float %x, i32 0
%vec2 = insertelement <2 x float> poison, float %y, i32 0
%vec3 = fcmp olt <2 x float> %vec1, %vec2
%res = extractelement <2 x i1> %vec3, i32 0
ret i1 %res
}
15 changes: 15 additions & 0 deletions tests/alive-tv/uf-float/vector-convert.srctgt.ll
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
; TEST-ARGS: --uf-float

define float @src(float noundef %x) {
%a = fptosi float %x to i32
%res = sitofp i32 %a to float
ret float %res
}

define float @tgt(float noundef %x) {
%vec1 = insertelement <4 x float> poison, float %x, i32 0
%vec2 = fptosi <4 x float> %vec1 to <4 x i32>
%vec3 = sitofp <4 x i32> %vec2 to <4 x float>
%res = extractelement <4 x float> %vec3, i32 0
ret float %res
}
13 changes: 13 additions & 0 deletions tests/alive-tv/uf-float/vector-unop.srctgt.ll
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
; TEST-ARGS: --uf-float

define float @src(float noundef %x) {
%res = fneg float %x
ret float %res
}

define float @tgt(float noundef %x) {
%vec1 = insertelement <2 x float> poison, float %x, i32 0
%vec2 = fneg <2 x float> %vec1
%res = extractelement <2 x float> %vec2, i32 0
ret float %res
}
5 changes: 5 additions & 0 deletions util/config.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ unsigned src_unroll_cnt = 0;
unsigned tgt_unroll_cnt = 0;
unsigned max_offset_bits = 64;
unsigned max_sizet_bits = 64;
FpEncodingMode fp_encoding_mode = FpEncodingMode::FloatingPoint;

ostream &dbg() {
return *debug_os;
Expand All @@ -32,4 +33,8 @@ void set_debug(ostream &os) {
debug_os = &os;
}

bool is_uf_float() {
return fp_encoding_mode == FpEncodingMode::UninterpretedFunctions;
}

}
8 changes: 8 additions & 0 deletions util/config.h
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,15 @@ extern unsigned max_offset_bits;
// size and size of pointers (not to be confused with program pointer size).
extern unsigned max_sizet_bits;

enum FpEncodingMode {
FloatingPoint,
UninterpretedFunctions
};

extern FpEncodingMode fp_encoding_mode;

std::ostream &dbg();
void set_debug(std::ostream &os);
bool is_uf_float();

}