Skip to content

Commit

Permalink
auto merge of #6625 : cmr/rust/constops, r=Aatch
Browse files Browse the repository at this point in the history
  • Loading branch information
bors committed May 20, 2013
2 parents 9283dfe + 808c5b8 commit cab9249
Show file tree
Hide file tree
Showing 3 changed files with 177 additions and 14 deletions.
18 changes: 16 additions & 2 deletions src/librustc/lib/llvm.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
// except according to those terms.

use core::hashmap::HashMap;
use core::libc::c_uint;
use core::libc::{c_uint, c_ushort};

pub type Opcode = u32;
pub type Bool = c_uint;
Expand Down Expand Up @@ -221,7 +221,7 @@ pub mod llvm {
use super::{SectionIteratorRef, TargetDataRef, TypeKind, TypeRef, UseRef};
use super::{ValueRef};

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

#[link_args = "-Lrustllvm -lrustllvm"]
#[link_name = "rustllvm"]
Expand Down Expand Up @@ -451,6 +451,10 @@ pub mod llvm {
/* all zeroes */
#[fast_ffi]
pub unsafe fn LLVMConstAllOnes(Ty: TypeRef) -> ValueRef;
#[fast_ffi]
pub unsafe fn LLVMConstICmp(Pred: c_ushort, V1: ValueRef, V2: ValueRef) -> ValueRef;
#[fast_ffi]
pub unsafe fn LLVMConstFCmp(Pred: c_ushort, V1: ValueRef, V2: ValueRef) -> ValueRef;
/* only for int/vector */
#[fast_ffi]
pub unsafe fn LLVMGetUndef(Ty: TypeRef) -> ValueRef;
Expand Down Expand Up @@ -1914,6 +1918,16 @@ pub fn SetLinkage(Global: ValueRef, Link: Linkage) {
}
}

pub fn ConstICmp(Pred: IntPredicate, V1: ValueRef, V2: ValueRef) -> ValueRef {
unsafe {
llvm::LLVMConstICmp(Pred as c_ushort, V1, V2)
}
}
pub fn ConstFCmp(Pred: RealPredicate, V1: ValueRef, V2: ValueRef) -> ValueRef {
unsafe {
llvm::LLVMConstFCmp(Pred as c_ushort, V1, V2)
}
}
/* Memory-managed object interface to type handles. */

pub struct TypeNames {
Expand Down
57 changes: 45 additions & 12 deletions src/librustc/middle/trans/consts.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,11 @@
// except according to those terms.

use back::abi;
use lib::llvm::{llvm, SetLinkage, PrivateLinkage,
ValueRef, TypeRef, Bool, True, False};
use lib::llvm::{llvm, ConstFCmp, ConstICmp, SetLinkage, PrivateLinkage, ValueRef, TypeRef, Bool,
True, False};
use lib::llvm::{IntEQ, IntNE, IntUGT, IntUGE, IntULT, IntULE, IntSGT, IntSGE, IntSLT, IntSLE,
RealOEQ, RealOGT, RealOGE, RealOLT, RealOLE, RealONE};

use metadata::csearch;
use middle::const_eval;
use middle::trans::adt;
Expand Down Expand Up @@ -280,8 +283,8 @@ fn const_expr_unadjusted(cx: @CrateContext, e: @ast::expr) -> ValueRef {
else if signed { llvm::LLVMConstSRem(te1, te2) }
else { llvm::LLVMConstURem(te1, te2) }
}
ast::and |
ast::or => cx.sess.span_unimpl(e.span, "binop logic"),
ast::and => llvm::LLVMConstAnd(te1, te2),
ast::or => llvm::LLVMConstOr(te1, te2),
ast::bitxor => llvm::LLVMConstXor(te1, te2),
ast::bitand => llvm::LLVMConstAnd(te1, te2),
ast::bitor => llvm::LLVMConstOr(te1, te2),
Expand All @@ -290,14 +293,44 @@ fn const_expr_unadjusted(cx: @CrateContext, e: @ast::expr) -> ValueRef {
if signed { llvm::LLVMConstAShr(te1, te2) }
else { llvm::LLVMConstLShr(te1, te2) }
}
ast::eq |
ast::lt |
ast::le |
ast::ne |
ast::ge |
ast::gt => cx.sess.span_unimpl(e.span, "binop comparator")
}
}
ast::eq => {
if is_float { ConstFCmp(RealOEQ, te1, te2) }
else { ConstICmp(IntEQ, te1, te2) }
},
ast::lt => {
if is_float { ConstFCmp(RealOLT, te1, te2) }
else {
if signed { ConstICmp(IntSLT, te1, te2) }
else { ConstICmp(IntULT, te1, te2) }
}
},
ast::le => {
if is_float { ConstFCmp(RealOLE, te1, te2) }
else {
if signed { ConstICmp(IntSLE, te1, te2) }
else { ConstICmp(IntULE, te1, te2) }
}
},
ast::ne => {
if is_float { ConstFCmp(RealONE, te1, te2) }
else { ConstICmp(IntNE, te1, te2) }
},
ast::ge => {
if is_float { ConstFCmp(RealOGE, te1, te2) }
else {
if signed { ConstICmp(IntSGE, te1, te2) }
else { ConstICmp(IntUGE, te1, te2) }
}
},
ast::gt => {
if is_float { ConstFCmp(RealOGT, te1, te2) }
else {
if signed { ConstICmp(IntSGT, te1, te2) }
else { ConstICmp(IntUGT, te1, te2) }
}
},
};
},
ast::expr_unary(u, e) => {
let te = const_expr(cx, e);
let ty = ty::expr_ty(cx.tcx, e);
Expand Down
116 changes: 116 additions & 0 deletions src/test/run-pass/const-binops.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,116 @@
static a: int = -4 + 3;
static a2: uint = 3 + 3;
static b: float = 3.0 + 2.7;

static c: int = 3 - 4;
static d: uint = 3 - 3;
static e: float = 3.0 - 2.7;

static e2: int = -3 * 3;
static f: uint = 3 * 3;
static g: float = 3.3 * 3.3;

static h: int = 3 / -1;
static i: uint = 3 / 3;
static j: float = 3.3 / 3.3;

static n: bool = true && false;

static o: bool = true || false;

static p: int = 3 & 1;
static q: uint = 1 & 3;

static r: int = 3 | 1;
static s: uint = 1 | 3;

static t: int = 3 ^ 1;
static u: uint = 1 ^ 3;

static v: int = 1 << 3;

// NOTE: better shr coverage
static w: int = 1024 >> 4;
static x: uint = 1024 >> 4;

static y: bool = 1 == 1;
static z: bool = 1.0 == 1.0;

static aa: bool = 1 <= 2;
static ab: bool = -1 <= 2;
static ac: bool = 1.0 <= 2.0;

static ad: bool = 1 < 2;
static ae: bool = -1 < 2;
static af: bool = 1.0 < 2.0;

static ag: bool = 1 != 2;
static ah: bool = -1 != 2;
static ai: bool = 1.0 != 2.0;

static aj: bool = 2 >= 1;
static ak: bool = 2 >= -2;
static al: bool = 1.0 >= -2.0;

static am: bool = 2 > 1;
static an: bool = 2 > -2;
static ao: bool = 1.0 > -2.0;

fn main() {
assert_eq!(a, -1);
assert_eq!(a2, 6);
assert_approx_eq!(b, 5.7);

assert_eq!(c, -1);
assert_eq!(d, 0);
assert_approx_eq!(e, 0.3);

assert_eq!(e2, -9);
assert_eq!(f, 9);
assert_approx_eq!(g, 10.89);

assert_eq!(h, -3);
assert_eq!(i, 1);
assert_approx_eq!(j, 1.0);

assert_eq!(n, false);

assert_eq!(o, true);

assert_eq!(p, 1);
assert_eq!(q, 1);

assert_eq!(r, 3);
assert_eq!(s, 3);

assert_eq!(t, 2);
assert_eq!(u, 2);

assert_eq!(v, 8);

assert_eq!(w, 64);
assert_eq!(x, 64);

assert_eq!(y, true);
assert_eq!(z, true);

assert_eq!(aa, true);
assert_eq!(ab, true);
assert_eq!(ac, true);

assert_eq!(ad, true);
assert_eq!(ae, true);
assert_eq!(af, true);

assert_eq!(ag, true);
assert_eq!(ah, true);
assert_eq!(ai, true);

assert_eq!(aj, true);
assert_eq!(ak, true);
assert_eq!(al, true);

assert_eq!(am, true);
assert_eq!(an, true);
assert_eq!(ao, true);
}

0 comments on commit cab9249

Please sign in to comment.