Skip to content

Commit e42fcb9

Browse files
committed
Implement unimplemented const binops
1 parent 7396f7f commit e42fcb9

File tree

3 files changed

+165
-12
lines changed

3 files changed

+165
-12
lines changed

src/librustc/lib/llvm.rs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -220,6 +220,7 @@ pub mod llvm {
220220
use super::{ObjectFileRef, Opcode, PassManagerRef, PassManagerBuilderRef};
221221
use super::{SectionIteratorRef, TargetDataRef, TypeKind, TypeRef, UseRef};
222222
use super::{ValueRef};
223+
use super::{IntPredicate, RealPredicate};
223224

224225
use core::libc::{c_char, c_int, c_longlong, c_uint, c_ulonglong};
225226

@@ -451,6 +452,10 @@ pub mod llvm {
451452
/* all zeroes */
452453
#[fast_ffi]
453454
pub unsafe fn LLVMConstAllOnes(Ty: TypeRef) -> ValueRef;
455+
#[fast_ffi]
456+
pub unsafe fn LLVMConstICmp(Pred: IntPredicate, V1: ValueRef, V2: ValueRef) -> ValueRef;
457+
#[fast_ffi]
458+
pub unsafe fn LLVMConstFCmp(Pred: RealPredicate, V1: ValueRef, V2: ValueRef) -> ValueRef;
454459
/* only for int/vector */
455460
#[fast_ffi]
456461
pub unsafe fn LLVMGetUndef(Ty: TypeRef) -> ValueRef;

src/librustc/middle/trans/consts.rs

Lines changed: 44 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -9,8 +9,10 @@
99
// except according to those terms.
1010

1111
use back::abi;
12-
use lib::llvm::{llvm, SetLinkage, PrivateLinkage,
13-
ValueRef, TypeRef, Bool, True, False};
12+
use lib::llvm::{llvm, SetLinkage, PrivateLinkage, ValueRef, TypeRef, Bool, True, False};
13+
use lib::llvm::{IntEQ, IntNE, IntUGT, IntUGE, IntULT, IntULE, IntSGT, IntSGE, IntSLT, IntSLE,
14+
RealOEQ, RealOGT, RealOGE, RealOLT, RealOLE, RealONE};
15+
1416
use metadata::csearch;
1517
use middle::const_eval;
1618
use middle::trans::adt;
@@ -280,8 +282,8 @@ fn const_expr_unadjusted(cx: @CrateContext, e: @ast::expr) -> ValueRef {
280282
else if signed { llvm::LLVMConstSRem(te1, te2) }
281283
else { llvm::LLVMConstURem(te1, te2) }
282284
}
283-
ast::and |
284-
ast::or => cx.sess.span_unimpl(e.span, "binop logic"),
285+
ast::and => llvm::LLVMConstAnd(te1, te2),
286+
ast::or => llvm::LLVMConstOr(te1, te2),
285287
ast::bitxor => llvm::LLVMConstXor(te1, te2),
286288
ast::bitand => llvm::LLVMConstAnd(te1, te2),
287289
ast::bitor => llvm::LLVMConstOr(te1, te2),
@@ -290,14 +292,44 @@ fn const_expr_unadjusted(cx: @CrateContext, e: @ast::expr) -> ValueRef {
290292
if signed { llvm::LLVMConstAShr(te1, te2) }
291293
else { llvm::LLVMConstLShr(te1, te2) }
292294
}
293-
ast::eq |
294-
ast::lt |
295-
ast::le |
296-
ast::ne |
297-
ast::ge |
298-
ast::gt => cx.sess.span_unimpl(e.span, "binop comparator")
299-
}
300-
}
295+
ast::eq => {
296+
if is_float { llvm::LLVMConstFCmp(RealOEQ, te1, te2) }
297+
else { llvm::LLVMConstICmp(IntEQ, te1, te2) }
298+
},
299+
ast::lt => {
300+
if is_float { llvm::LLVMConstFCmp(RealOLT, te1, te2) }
301+
else {
302+
if signed { llvm::LLVMConstICmp(IntSLT, te1, te2) }
303+
else { llvm::LLVMConstICmp(IntULT, te1, te2) }
304+
}
305+
},
306+
ast::le => {
307+
if is_float { llvm::LLVMConstFCmp(RealOLE, te1, te2) }
308+
else {
309+
if signed { llvm::LLVMConstICmp(IntSLE, te1, te2) }
310+
else { llvm::LLVMConstICmp(IntULE, te1, te2) }
311+
}
312+
},
313+
ast::ne => {
314+
if is_float { llvm::LLVMConstFCmp(RealONE, te1, te2) }
315+
else { llvm::LLVMConstICmp(IntNE, te1, te2) }
316+
},
317+
ast::ge => {
318+
if is_float { llvm::LLVMConstFCmp(RealOGE, te1, te2) }
319+
else {
320+
if signed { llvm::LLVMConstICmp(IntSGE, te1, te2) }
321+
else { llvm::LLVMConstICmp(IntUGE, te1, te2) }
322+
}
323+
},
324+
ast::gt => {
325+
if is_float { llvm::LLVMConstFCmp(RealOGT, te1, te2) }
326+
else {
327+
if signed { llvm::LLVMConstICmp(IntSGT, te1, te2) }
328+
else { llvm::LLVMConstICmp(IntUGT, te1, te2) }
329+
}
330+
},
331+
};
332+
},
301333
ast::expr_unary(u, e) => {
302334
let te = const_expr(cx, e);
303335
let ty = ty::expr_ty(cx.tcx, e);

src/test/run-pass/const-binops.rs

Lines changed: 116 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,116 @@
1+
static a: int = -4 + 3;
2+
static a2: uint = 3 + 3;
3+
static b: float = 3.0 + 2.7;
4+
5+
static c: int = 3 - 4;
6+
static d: uint = 3 - 3;
7+
static e: float = 3.0 - 2.7;
8+
9+
static e2: int = -3 * 3;
10+
static f: uint = 3 * 3;
11+
static g: float = 3.3 * 3.3;
12+
13+
static h: int = 3 / -1;
14+
static i: uint = 3 / 3;
15+
static j: float = 3.3 / 3.3;
16+
17+
static n: bool = true && false;
18+
19+
static o: bool = true || false;
20+
21+
static p: int = 3 & 1;
22+
static q: uint = 1 & 3;
23+
24+
static r: int = 3 | 1;
25+
static s: uint = 1 | 3;
26+
27+
static t: int = 3 ^ 1;
28+
static u: uint = 1 ^ 3;
29+
30+
static v: int = 1 << 3;
31+
32+
// NOTE: better shr coverage
33+
static w: int = 1024 >> 4;
34+
static x: uint = 1024 >> 4;
35+
36+
static y: bool = 1 == 1;
37+
static z: bool = 1.0 == 1.0;
38+
39+
static aa: bool = 1 <= 2;
40+
static ab: bool = -1 <= 2;
41+
static ac: bool = 1.0 <= 2;
42+
43+
static ad: bool = 1 < 2;
44+
static ae: bool = -1 < 2;
45+
static af: bool = 1.0 < 2;
46+
47+
static ag: bool = 1 != 2;
48+
static ah: bool = -1 != 2;
49+
static ai: bool = 1.0 != 2;
50+
51+
static aj: bool = 2 >= 1;
52+
static ak: bool = 2 >= -2;
53+
static al: bool = 1.0 >= -2;
54+
55+
static am: bool = 2 > 1;
56+
static an: bool = 2 > -2;
57+
static ao: bool = 1.0 > -2;
58+
59+
fn main() {
60+
assert_eq!(a, -1);
61+
assert_eq!(a2, 6);
62+
assert_approx_eq!(b, 5.7);
63+
64+
assert_eq!(c, -1);
65+
assert_eq!(d, 0);
66+
assert_approx_eq!(e, -0.3);
67+
68+
assert_eq!(e2, -9);
69+
assert_eq!(f, 9);
70+
assert_approx_eq!(g, 10.89);
71+
72+
assert_eq!(h, -3);
73+
assert_eq!(i, 1);
74+
assert_approx_eq!(j, 1.0);
75+
76+
assert_eq!(n, false);
77+
78+
assert_eq!(o, true);
79+
80+
assert_eq!(p, 1);
81+
assert_eq!(q, 1);
82+
83+
assert_eq!(r, 3);
84+
assert_eq!(s, 3);
85+
86+
assert_eq!(t, 2);
87+
assert_eq!(u, 2);
88+
89+
assert_eq!(v, 8);
90+
91+
assert_eq!(w, 64);
92+
assert_eq!(x, 64);
93+
94+
assert_eq!(y, true);
95+
assert_eq!(z, true);
96+
97+
assert_eq!(aa, true);
98+
assert_eq!(ab, true);
99+
assert_eq!(ac, true);
100+
101+
assert_eq!(ad, true);
102+
assert_eq!(ae, true);
103+
assert_eq!(af, true);
104+
105+
assert_eq!(ag, true);
106+
assert_eq!(ah, true);
107+
assert_eq!(ai, true);
108+
109+
assert_eq!(aj, true);
110+
assert_eq!(ak, true);
111+
assert_eq!(al, true);
112+
113+
assert_eq!(am, true);
114+
assert_eq!(an, true);
115+
assert_eq!(ao, true);
116+
}

0 commit comments

Comments
 (0)