diff --git a/expr.cpp b/expr.cpp index 718abe2b..5eb30755 100644 --- a/expr.cpp +++ b/expr.cpp @@ -799,11 +799,17 @@ lOpString(BinaryExpr::Op op) { */ static llvm::Value * lEmitBinaryBitOp(BinaryExpr::Op op, llvm::Value *arg0Val, - llvm::Value *arg1Val, FunctionEmitContext *ctx) { + llvm::Value *arg1Val, bool isUnsigned, + FunctionEmitContext *ctx) { llvm::Instruction::BinaryOps inst; switch (op) { case BinaryExpr::Shl: inst = llvm::Instruction::Shl; break; - case BinaryExpr::Shr: inst = llvm::Instruction::AShr; break; + case BinaryExpr::Shr: + if (isUnsigned) + inst = llvm::Instruction::LShr; + else + inst = llvm::Instruction::AShr; + break; case BinaryExpr::BitAnd: inst = llvm::Instruction::And; break; case BinaryExpr::BitXor: inst = llvm::Instruction::Xor; break; case BinaryExpr::BitOr: inst = llvm::Instruction::Or; break; @@ -949,7 +955,8 @@ BinaryExpr::GetValue(FunctionEmitContext *ctx) const { dynamic_cast(arg1) == NULL) PerformanceWarning(pos, "Shift right is extremely inefficient for " "varying shift amounts."); - return lEmitBinaryBitOp(op, e0Val, e1Val, ctx); + return lEmitBinaryBitOp(op, e0Val, e1Val, + arg0->GetType()->IsUnsignedType(), ctx); } case LogicalAnd: return ctx->BinaryOperator(llvm::Instruction::And, e0Val, e1Val, @@ -1533,7 +1540,8 @@ lEmitOpAssign(AssignExpr::Op op, Expr *arg0, Expr *arg1, const Type *type, case AssignExpr::AndAssign: case AssignExpr::XorAssign: case AssignExpr::OrAssign: - newValue = lEmitBinaryBitOp(basicop, oldLHS, rvalue, ctx); + newValue = lEmitBinaryBitOp(basicop, oldLHS, rvalue, + arg0->GetType()->IsUnsignedType(), ctx); break; default: FATAL("logic error in lEmitOpAssign"); diff --git a/tests/uint-shift.ispc b/tests/uint-shift.ispc new file mode 100644 index 00000000..6c0eba39 --- /dev/null +++ b/tests/uint-shift.ispc @@ -0,0 +1,11 @@ + +export uniform int width() { return programCount; } + +export void f_f(uniform float RET[], uniform float aFOO[]) { + unsigned int x = 0xffffffff; + RET[programIndex] = x >> 16; +} + +export void result(uniform float RET[]) { + RET[programIndex] = 0xffff; +}