authorgravatar for william@sengir.comWilliam Sengir <william@sengir.com> 2022-03-19 23:57:29-07:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2022-03-21 16:54:19-07:00
log961248cde32e0d572225c6c1d367b960540ae220
tree0e73eacaacdb252321029040743fb6120b307af5
parentb96699059c6224b0a425f2fe5010469ef6049cad

stage2: make more instructions vector-compatible in LLVM backend


1 files changed, 80 insertions(+), 39 deletions(-)

src/codegen/llvm.zig+80-39
......@@ -3960,10 +3960,11 @@ pub const FuncGen = struct {
39603960 const ty_op = self.air.instructions.items(.data)[inst].ty_op;
39613961 const operand = try self.resolveInst(ty_op.operand);
39623962 const operand_ty = self.air.typeOf(ty_op.operand);
3963 const operand_scalar_ty = operand_ty.scalarType();
39633964 const dest_ty = self.air.typeOfIndex(inst);
39643965 const dest_llvm_ty = try self.dg.llvmType(dest_ty);
39653966
3966 if (operand_ty.isSignedInt()) {
3967 if (operand_scalar_ty.isSignedInt()) {
39673968 return self.builder.buildSIToFP(operand, dest_llvm_ty, "");
39683969 } else {
39693970 return self.builder.buildUIToFP(operand, dest_llvm_ty, "");
......@@ -3977,11 +3978,12 @@ pub const FuncGen = struct {
39773978 const ty_op = self.air.instructions.items(.data)[inst].ty_op;
39783979 const operand = try self.resolveInst(ty_op.operand);
39793980 const dest_ty = self.air.typeOfIndex(inst);
3981 const dest_scalar_ty = dest_ty.scalarType();
39803982 const dest_llvm_ty = try self.dg.llvmType(dest_ty);
39813983
39823984 // TODO set fast math flag
39833985
3984 if (dest_ty.isSignedInt()) {
3986 if (dest_scalar_ty.isSignedInt()) {
39853987 return self.builder.buildFPToSI(operand, dest_llvm_ty, "");
39863988 } else {
39873989 return self.builder.buildFPToUI(operand, dest_llvm_ty, "");
......@@ -4912,9 +4914,10 @@ pub const FuncGen = struct {
49124914 const lhs = try self.resolveInst(bin_op.lhs);
49134915 const rhs = try self.resolveInst(bin_op.rhs);
49144916 const inst_ty = self.air.typeOfIndex(inst);
4917 const scalar_ty = inst_ty.scalarType();
49154918
4916 if (inst_ty.isAnyFloat()) return self.builder.buildFAdd(lhs, rhs, "");
4917 if (inst_ty.isSignedInt()) return self.builder.buildNSWAdd(lhs, rhs, "");
4919 if (scalar_ty.isAnyFloat()) return self.builder.buildFAdd(lhs, rhs, "");
4920 if (scalar_ty.isSignedInt()) return self.builder.buildNSWAdd(lhs, rhs, "");
49184921 return self.builder.buildNUWAdd(lhs, rhs, "");
49194922 }
49204923
......@@ -4935,9 +4938,10 @@ pub const FuncGen = struct {
49354938 const lhs = try self.resolveInst(bin_op.lhs);
49364939 const rhs = try self.resolveInst(bin_op.rhs);
49374940 const inst_ty = self.air.typeOfIndex(inst);
4941 const scalar_ty = inst_ty.scalarType();
49384942
4939 if (inst_ty.isAnyFloat()) return self.todo("saturating float add", .{});
4940 if (inst_ty.isSignedInt()) return self.builder.buildSAddSat(lhs, rhs, "");
4943 if (scalar_ty.isAnyFloat()) return self.todo("saturating float add", .{});
4944 if (scalar_ty.isSignedInt()) return self.builder.buildSAddSat(lhs, rhs, "");
49414945
49424946 return self.builder.buildUAddSat(lhs, rhs, "");
49434947 }
......@@ -4949,9 +4953,10 @@ pub const FuncGen = struct {
49494953 const lhs = try self.resolveInst(bin_op.lhs);
49504954 const rhs = try self.resolveInst(bin_op.rhs);
49514955 const inst_ty = self.air.typeOfIndex(inst);
4956 const scalar_ty = inst_ty.scalarType();
49524957
4953 if (inst_ty.isAnyFloat()) return self.builder.buildFSub(lhs, rhs, "");
4954 if (inst_ty.isSignedInt()) return self.builder.buildNSWSub(lhs, rhs, "");
4958 if (scalar_ty.isAnyFloat()) return self.builder.buildFSub(lhs, rhs, "");
4959 if (scalar_ty.isSignedInt()) return self.builder.buildNSWSub(lhs, rhs, "");
49554960 return self.builder.buildNUWSub(lhs, rhs, "");
49564961 }
49574962
......@@ -4972,9 +4977,10 @@ pub const FuncGen = struct {
49724977 const lhs = try self.resolveInst(bin_op.lhs);
49734978 const rhs = try self.resolveInst(bin_op.rhs);
49744979 const inst_ty = self.air.typeOfIndex(inst);
4980 const scalar_ty = inst_ty.scalarType();
49754981
4976 if (inst_ty.isAnyFloat()) return self.todo("saturating float sub", .{});
4977 if (inst_ty.isSignedInt()) return self.builder.buildSSubSat(lhs, rhs, "");
4982 if (scalar_ty.isAnyFloat()) return self.todo("saturating float sub", .{});
4983 if (scalar_ty.isSignedInt()) return self.builder.buildSSubSat(lhs, rhs, "");
49784984 return self.builder.buildUSubSat(lhs, rhs, "");
49794985 }
49804986
......@@ -4985,9 +4991,10 @@ pub const FuncGen = struct {
49854991 const lhs = try self.resolveInst(bin_op.lhs);
49864992 const rhs = try self.resolveInst(bin_op.rhs);
49874993 const inst_ty = self.air.typeOfIndex(inst);
4994 const scalar_ty = inst_ty.scalarType();
49884995
4989 if (inst_ty.isAnyFloat()) return self.builder.buildFMul(lhs, rhs, "");
4990 if (inst_ty.isSignedInt()) return self.builder.buildNSWMul(lhs, rhs, "");
4996 if (scalar_ty.isAnyFloat()) return self.builder.buildFMul(lhs, rhs, "");
4997 if (scalar_ty.isSignedInt()) return self.builder.buildNSWMul(lhs, rhs, "");
49914998 return self.builder.buildNUWMul(lhs, rhs, "");
49924999 }
49935000
......@@ -5008,9 +5015,10 @@ pub const FuncGen = struct {
50085015 const lhs = try self.resolveInst(bin_op.lhs);
50095016 const rhs = try self.resolveInst(bin_op.rhs);
50105017 const inst_ty = self.air.typeOfIndex(inst);
5018 const scalar_ty = inst_ty.scalarType();
50115019
5012 if (inst_ty.isAnyFloat()) return self.todo("saturating float mul", .{});
5013 if (inst_ty.isSignedInt()) return self.builder.buildSMulFixSat(lhs, rhs, "");
5020 if (scalar_ty.isAnyFloat()) return self.todo("saturating float mul", .{});
5021 if (scalar_ty.isSignedInt()) return self.builder.buildSMulFixSat(lhs, rhs, "");
50145022 return self.builder.buildUMulFixSat(lhs, rhs, "");
50155023 }
50165024
......@@ -5031,12 +5039,13 @@ pub const FuncGen = struct {
50315039 const lhs = try self.resolveInst(bin_op.lhs);
50325040 const rhs = try self.resolveInst(bin_op.rhs);
50335041 const inst_ty = self.air.typeOfIndex(inst);
5042 const scalar_ty = inst_ty.scalarType();
50345043
5035 if (inst_ty.isRuntimeFloat()) {
5044 if (scalar_ty.isRuntimeFloat()) {
50365045 const result = self.builder.buildFDiv(lhs, rhs, "");
50375046 return self.callTrunc(result, inst_ty);
50385047 }
5039 if (inst_ty.isSignedInt()) return self.builder.buildSDiv(lhs, rhs, "");
5048 if (scalar_ty.isSignedInt()) return self.builder.buildSDiv(lhs, rhs, "");
50405049 return self.builder.buildUDiv(lhs, rhs, "");
50415050 }
50425051
......@@ -5047,12 +5056,13 @@ pub const FuncGen = struct {
50475056 const lhs = try self.resolveInst(bin_op.lhs);
50485057 const rhs = try self.resolveInst(bin_op.rhs);
50495058 const inst_ty = self.air.typeOfIndex(inst);
5059 const scalar_ty = inst_ty.scalarType();
50505060
5051 if (inst_ty.isRuntimeFloat()) {
5061 if (scalar_ty.isRuntimeFloat()) {
50525062 const result = self.builder.buildFDiv(lhs, rhs, "");
50535063 return try self.callFloor(result, inst_ty);
50545064 }
5055 if (inst_ty.isSignedInt()) {
5065 if (scalar_ty.isSignedInt()) {
50565066 // const d = @divTrunc(a, b);
50575067 // const r = @rem(a, b);
50585068 // return if (r == 0) d else d - ((a < 0) ^ (b < 0));
......@@ -5078,9 +5088,10 @@ pub const FuncGen = struct {
50785088 const lhs = try self.resolveInst(bin_op.lhs);
50795089 const rhs = try self.resolveInst(bin_op.rhs);
50805090 const inst_ty = self.air.typeOfIndex(inst);
5091 const scalar_ty = inst_ty.scalarType();
50815092
5082 if (inst_ty.isRuntimeFloat()) return self.builder.buildFDiv(lhs, rhs, "");
5083 if (inst_ty.isSignedInt()) return self.builder.buildExactSDiv(lhs, rhs, "");
5093 if (scalar_ty.isRuntimeFloat()) return self.builder.buildFDiv(lhs, rhs, "");
5094 if (scalar_ty.isSignedInt()) return self.builder.buildExactSDiv(lhs, rhs, "");
50845095 return self.builder.buildExactUDiv(lhs, rhs, "");
50855096 }
50865097
......@@ -5091,9 +5102,10 @@ pub const FuncGen = struct {
50915102 const lhs = try self.resolveInst(bin_op.lhs);
50925103 const rhs = try self.resolveInst(bin_op.rhs);
50935104 const inst_ty = self.air.typeOfIndex(inst);
5105 const scalar_ty = inst_ty.scalarType();
50945106
5095 if (inst_ty.isRuntimeFloat()) return self.builder.buildFRem(lhs, rhs, "");
5096 if (inst_ty.isSignedInt()) return self.builder.buildSRem(lhs, rhs, "");
5107 if (scalar_ty.isRuntimeFloat()) return self.builder.buildFRem(lhs, rhs, "");
5108 if (scalar_ty.isSignedInt()) return self.builder.buildSRem(lhs, rhs, "");
50975109 return self.builder.buildURem(lhs, rhs, "");
50985110 }
50995111
......@@ -5105,8 +5117,9 @@ pub const FuncGen = struct {
51055117 const rhs = try self.resolveInst(bin_op.rhs);
51065118 const inst_ty = self.air.typeOfIndex(inst);
51075119 const inst_llvm_ty = try self.dg.llvmType(inst_ty);
5120 const scalar_ty = inst_ty.scalarType();
51085121
5109 if (inst_ty.isRuntimeFloat()) {
5122 if (scalar_ty.isRuntimeFloat()) {
51105123 const a = self.builder.buildFRem(lhs, rhs, "");
51115124 const b = self.builder.buildFAdd(a, rhs, "");
51125125 const c = self.builder.buildFRem(b, rhs, "");
......@@ -5114,7 +5127,7 @@ pub const FuncGen = struct {
51145127 const ltz = self.builder.buildFCmp(.OLT, lhs, zero, "");
51155128 return self.builder.buildSelect(ltz, c, a, "");
51165129 }
5117 if (inst_ty.isSignedInt()) {
5130 if (scalar_ty.isSignedInt()) {
51185131 const a = self.builder.buildSRem(lhs, rhs, "");
51195132 const b = self.builder.buildNSWAdd(a, rhs, "");
51205133 const c = self.builder.buildSRem(b, rhs, "");
......@@ -5339,15 +5352,22 @@ pub const FuncGen = struct {
53395352 if (self.liveness.isUnused(inst)) return null;
53405353
53415354 const bin_op = self.air.instructions.items(.data)[inst].bin_op;
5355
53425356 const lhs = try self.resolveInst(bin_op.lhs);
53435357 const rhs = try self.resolveInst(bin_op.rhs);
5344 const lhs_type = self.air.typeOf(bin_op.lhs);
5358
5359 const lhs_ty = self.air.typeOf(bin_op.lhs);
5360 const rhs_ty = self.air.typeOf(bin_op.rhs);
5361 const lhs_scalar_ty = lhs_ty.scalarType();
5362 const rhs_scalar_ty = rhs_ty.scalarType();
5363
53455364 const tg = self.dg.module.getTarget();
5346 const casted_rhs = if (self.air.typeOf(bin_op.rhs).bitSize(tg) < lhs_type.bitSize(tg))
5347 self.builder.buildZExt(rhs, try self.dg.llvmType(lhs_type), "")
5365
5366 const casted_rhs = if (rhs_scalar_ty.bitSize(tg) < lhs_scalar_ty.bitSize(tg))
5367 self.builder.buildZExt(rhs, try self.dg.llvmType(lhs_ty), "")
53485368 else
53495369 rhs;
5350 if (lhs_type.isSignedInt()) return self.builder.buildNSWShl(lhs, casted_rhs, "");
5370 if (lhs_scalar_ty.isSignedInt()) return self.builder.buildNSWShl(lhs, casted_rhs, "");
53515371 return self.builder.buildNUWShl(lhs, casted_rhs, "");
53525372 }
53535373
......@@ -5355,11 +5375,18 @@ pub const FuncGen = struct {
53555375 if (self.liveness.isUnused(inst)) return null;
53565376
53575377 const bin_op = self.air.instructions.items(.data)[inst].bin_op;
5378
53585379 const lhs = try self.resolveInst(bin_op.lhs);
53595380 const rhs = try self.resolveInst(bin_op.rhs);
5381
53605382 const lhs_type = self.air.typeOf(bin_op.lhs);
5383 const rhs_type = self.air.typeOf(bin_op.rhs);
5384 const lhs_scalar_ty = lhs_type.scalarType();
5385 const rhs_scalar_ty = rhs_type.scalarType();
5386
53615387 const tg = self.dg.module.getTarget();
5362 const casted_rhs = if (self.air.typeOf(bin_op.rhs).bitSize(tg) < lhs_type.bitSize(tg))
5388
5389 const casted_rhs = if (rhs_scalar_ty.bitSize(tg) < lhs_scalar_ty.bitSize(tg))
53635390 self.builder.buildZExt(rhs, try self.dg.llvmType(lhs_type), "")
53645391 else
53655392 rhs;
......@@ -5370,31 +5397,45 @@ pub const FuncGen = struct {
53705397 if (self.liveness.isUnused(inst)) return null;
53715398
53725399 const bin_op = self.air.instructions.items(.data)[inst].bin_op;
5400
53735401 const lhs = try self.resolveInst(bin_op.lhs);
53745402 const rhs = try self.resolveInst(bin_op.rhs);
5375 const lhs_type = self.air.typeOf(bin_op.lhs);
5403
5404 const lhs_ty = self.air.typeOf(bin_op.lhs);
5405 const rhs_ty = self.air.typeOf(bin_op.rhs);
5406 const lhs_scalar_ty = lhs_ty.scalarType();
5407 const rhs_scalar_ty = rhs_ty.scalarType();
5408
53765409 const tg = self.dg.module.getTarget();
5377 const casted_rhs = if (self.air.typeOf(bin_op.rhs).bitSize(tg) < lhs_type.bitSize(tg))
5378 self.builder.buildZExt(rhs, try self.dg.llvmType(lhs_type), "")
5410
5411 const casted_rhs = if (rhs_scalar_ty.bitSize(tg) < lhs_scalar_ty.bitSize(tg))
5412 self.builder.buildZExt(rhs, try self.dg.llvmType(lhs_ty), "")
53795413 else
53805414 rhs;
5381 if (lhs_type.isSignedInt()) return self.builder.buildSShlSat(lhs, casted_rhs, "");
5415 if (lhs_scalar_ty.isSignedInt()) return self.builder.buildSShlSat(lhs, casted_rhs, "");
53825416 return self.builder.buildUShlSat(lhs, casted_rhs, "");
53835417 }
53845418
53855419 fn airShr(self: *FuncGen, inst: Air.Inst.Index, is_exact: bool) !?*const llvm.Value {
5386 if (self.liveness.isUnused(inst))
5387 return null;
5420 if (self.liveness.isUnused(inst)) return null;
5421
53885422 const bin_op = self.air.instructions.items(.data)[inst].bin_op;
5423
53895424 const lhs = try self.resolveInst(bin_op.lhs);
53905425 const rhs = try self.resolveInst(bin_op.rhs);
5391 const lhs_type = self.air.typeOf(bin_op.lhs);
5426
5427 const lhs_ty = self.air.typeOf(bin_op.lhs);
5428 const rhs_ty = self.air.typeOf(bin_op.rhs);
5429 const lhs_scalar_ty = lhs_ty.scalarType();
5430 const rhs_scalar_ty = rhs_ty.scalarType();
5431
53925432 const tg = self.dg.module.getTarget();
5393 const casted_rhs = if (self.air.typeOf(bin_op.rhs).bitSize(tg) < lhs_type.bitSize(tg))
5394 self.builder.buildZExt(rhs, try self.dg.llvmType(lhs_type), "")
5433
5434 const casted_rhs = if (rhs_scalar_ty.bitSize(tg) < lhs_scalar_ty.bitSize(tg))
5435 self.builder.buildZExt(rhs, try self.dg.llvmType(lhs_ty), "")
53955436 else
53965437 rhs;
5397 const is_signed_int = self.air.typeOfIndex(inst).isSignedInt();
5438 const is_signed_int = lhs_scalar_ty.isSignedInt();
53985439
53995440 if (is_exact) {
54005441 if (is_signed_int) {