diff --git a/cl/_testrt/mask/in.go b/cl/_testrt/mask/in.go new file mode 100644 index 00000000..18211c06 --- /dev/null +++ b/cl/_testrt/mask/in.go @@ -0,0 +1,8 @@ +package main + +func main() { + println(mask(1)) +} +func mask(x int8) int32 { + return int32(x) << 31 >> 31 +} diff --git a/cl/_testrt/mask/out.ll b/cl/_testrt/mask/out.ll new file mode 100644 index 00000000..bea4f657 --- /dev/null +++ b/cl/_testrt/mask/out.ll @@ -0,0 +1,52 @@ +; ModuleID = 'main' +source_filename = "main" + +%"github.com/goplus/llgo/internal/runtime.String" = type { ptr, i64 } + +@"main.init$guard" = global ptr null +@__llgo_argc = global ptr null +@__llgo_argv = global ptr null +@0 = private unnamed_addr constant [2 x i8] c"\0A\00", align 1 + +define void @main.init() { +_llgo_0: + %0 = load i1, ptr @"main.init$guard", align 1 + br i1 %0, label %_llgo_2, label %_llgo_1 + +_llgo_1: ; preds = %_llgo_0 + store i1 true, ptr @"main.init$guard", align 1 + br label %_llgo_2 + +_llgo_2: ; preds = %_llgo_1, %_llgo_0 + ret void +} + +define void @main(i32 %0, ptr %1) { +_llgo_0: + store i32 %0, ptr @__llgo_argc, align 4 + store ptr %1, ptr @__llgo_argv, align 8 + call void @"github.com/goplus/llgo/internal/runtime.init"() + call void @main.init() + %2 = call i32 @main.mask(i8 1) + %3 = sext i32 %2 to i64 + call void @"github.com/goplus/llgo/internal/runtime.PrintInt"(i64 %3) + %4 = call %"github.com/goplus/llgo/internal/runtime.String" @"github.com/goplus/llgo/internal/runtime.NewString"(ptr @0, i64 1) + call void @"github.com/goplus/llgo/internal/runtime.PrintString"(%"github.com/goplus/llgo/internal/runtime.String" %4) + ret void +} + +define i32 @main.mask(i8 %0) { +_llgo_0: + %1 = sext i8 %0 to i32 + %2 = shl i32 %1, 31 + %3 = ashr i32 %2, 31 + ret i32 %3 +} + +declare void @"github.com/goplus/llgo/internal/runtime.init"() + +declare void @"github.com/goplus/llgo/internal/runtime.PrintInt"(i64) + +declare void @"github.com/goplus/llgo/internal/runtime.PrintString"(%"github.com/goplus/llgo/internal/runtime.String") + +declare %"github.com/goplus/llgo/internal/runtime.String" @"github.com/goplus/llgo/internal/runtime.NewString"(ptr, i64) diff --git a/ssa/expr.go b/ssa/expr.go index 89d70c55..7dfa45a0 100644 --- a/ssa/expr.go +++ b/ssa/expr.go @@ -328,6 +328,11 @@ func (b Builder) BinOp(op token.Token, x, y Expr) Expr { if op == token.SHR && kind == vkUnsigned { llop = llvm.LShr // Logical Shift Right } + if op == token.SHL || op == token.SHR { + if b.Prog.SizeOf(x.Type) != b.Prog.SizeOf(y.Type) { + y = b.Convert(x.Type, y) + } + } return Expr{llvm.CreateBinOp(b.impl, llop, x.impl, y.impl), x.Type} case isPredOp(op): // op: == != < <= < >= tret := b.Prog.Bool()