diff --git a/techlibs/ice40/arith_map.v b/techlibs/ice40/arith_map.v
index 4449fdc1b..eefc375dd 100644
--- a/techlibs/ice40/arith_map.v
+++ b/techlibs/ice40/arith_map.v
@@ -44,25 +44,32 @@ module _80_ice40_alu (A, B, CI, BI, X, Y, CO);
 
 	genvar i;
 	generate for (i = 0; i < Y_WIDTH; i = i + 1) begin:slice
-		SB_CARRY carry (
-			.I0(AA[i]),
-			.I1(BB[i]),
-			.CI(C[i]),
-			.CO(CO[i])
-		);
-		SB_LUT4 #(
-			//         I0: 1010 1010 1010 1010
-			//         I1: 1100 1100 1100 1100
-			//         I2: 1111 0000 1111 0000
-			//         I3: 1111 1111 0000 0000
-			.LUT_INIT(16'b 0110_1001_1001_0110)
-		) adder (
-			.I0(1'b0),
+		ICE40_CARRY_LUT carry_lut (
 			.I1(AA[i]),
 			.I2(BB[i]),
-			.I3(C[i]),
+			.CI(C[i]),
+			.CO(CO[i]),
 			.O(Y[i])
 		);
+//		SB_CARRY carry (
+//			.I0(AA[i]),
+//			.I1(BB[i]),
+//			.CI(C[i]),
+//			.CO(CO[i])
+//		);
+//		SB_LUT4 #(
+//			//         I0: 1010 1010 1010 1010
+//			//         I1: 1100 1100 1100 1100
+//			//         I2: 1111 0000 1111 0000
+//			//         I3: 1111 1111 0000 0000
+//			.LUT_INIT(16'b 0110_1001_1001_0110)
+//		) adder (
+//			.I0(1'b0),
+//			.I1(AA[i]),
+//			.I2(BB[i]),
+//			.I3(C[i]),
+//			.O(Y[i])
+//		);
 	end endgenerate
 
 	assign X = AA ^ BB;
diff --git a/techlibs/ice40/cells.box b/techlibs/ice40/cells.box
index d775efa78..34d1f372e 100644
--- a/techlibs/ice40/cells.box
+++ b/techlibs/ice40/cells.box
@@ -2,12 +2,8 @@
 
 # NB: Inputs/Outputs must be ordered alphabetically
 
-# Inputs: CI I0 I1
-# Outputs: CO
-SB_CARRY 1 1 3 1
+# Inputs: CI I1 I2
+# Outputs: CO O
+ICE40_CARRY_LUT 1 1 3 2
 126 259 231
-
-# Inputs: I0 I1 I2 I3
-# Outputs: O
-SB_LUT4 2 1 4 1
-316 379 400 449
+316 400 379
diff --git a/techlibs/ice40/cells_box.v b/techlibs/ice40/cells_box.v
index e2a54a42c..d0eb8708c 100644
--- a/techlibs/ice40/cells_box.v
+++ b/techlibs/ice40/cells_box.v
@@ -1,12 +1,18 @@
 (* abc_box_id = 1 *)
-module SB_CARRY (output CO, input CI, I0, I1);
-	assign CO = (I0 && I1) || ((I0 || I1) && CI);
-endmodule
+module ICE40_CARRY_LUT (output CO, O, input CI, I1, I2);
+	assign CO = (I1 && I2) || ((I1 || I2) && CI);
 
-(* abc_box_id = 2 *)
-module SB_LUT4 (output O, input I0, I1, I2, I3);
-	parameter [15:0] LUT_INIT = 0;
-	// Indicate this is a black-box
-	assign O = 1'b0;
-endmodule
+	wire I0, I3;
+	assign I0 = 1'b0;
+	assign I3 = CI;
 
+	//                            I0: 1010 1010 1010 1010
+	//                            I1: 1100 1100 1100 1100
+	//                            I2: 1111 0000 1111 0000
+	//                            I3: 1111 1111 0000 0000
+	localparam [15:0] LUT_INIT = 16'b 0110_1001_1001_0110;
+	wire [7:0] s3 = I3 ? LUT_INIT[15:8] : LUT_INIT[7:0];
+	wire [3:0] s2 = I2 ?       s3[ 7:4] :       s3[3:0];
+	wire [1:0] s1 = I1 ?       s2[ 3:2] :       s2[1:0];
+	assign O = I0 ? s1[1] : s1[0];
+endmodule
diff --git a/techlibs/ice40/cells_map.v b/techlibs/ice40/cells_map.v
index d0ddfd02e..d4c611686 100644
--- a/techlibs/ice40/cells_map.v
+++ b/techlibs/ice40/cells_map.v
@@ -57,3 +57,27 @@ module \$lut (A, Y);
   endgenerate
 endmodule
 `endif
+
+`ifndef NO_CARRY
+module ICE40_CARRY_LUT (output CO, O, input CI, I1, I2);
+	SB_CARRY carry (
+		.I0(I1),
+		.I1(I2),
+		.CI(CI),
+		.CO(CO),
+	);
+	SB_LUT4 #(
+		//         I0: 1010 1010 1010 1010
+		//         I1: 1100 1100 1100 1100
+		//         I2: 1111 0000 1111 0000
+		//         I3: 1111 1111 0000 0000
+		.LUT_INIT(16'b 0110_1001_1001_0110)
+	) adder (
+		.I0(1'b0),
+		.I1(I1),
+		.I2(I2),
+		.I3(CI),
+		.O(O)
+	);
+endmodule
+`endif
diff --git a/techlibs/ice40/cells_sim.v b/techlibs/ice40/cells_sim.v
index 322c1e5c7..b5a739a63 100644
--- a/techlibs/ice40/cells_sim.v
+++ b/techlibs/ice40/cells_sim.v
@@ -1384,3 +1384,25 @@ module SB_MAC16 (
 	assign LCI = (BOTADDSUB_CARRYSELECT == 0) ? 1'b0 : (BOTADDSUB_CARRYSELECT == 1) ? 1'b1 : (BOTADDSUB_CARRYSELECT == 2) ? ACCUMCI : CI;
 	assign O = {Oh, Ol};
 endmodule
+
+module ICE40_CARRY_LUT (input CI, input I1, input I2, output CO, output O);
+	SB_CARRY carry (
+		.I0(I1),
+		.I1(I2),
+		.CI(CI),
+		.CO(CO),
+	);
+	SB_LUT4 #(
+		//         I0: 1010 1010 1010 1010
+		//         I1: 1100 1100 1100 1100
+		//         I2: 1111 0000 1111 0000
+		//         I3: 1111 1111 0000 0000
+		.LUT_INIT(16'b 0110_1001_1001_0110)
+	) adder (
+		.I0(1'b0),
+		.I1(I1),
+		.I2(I2),
+		.I3(CI),
+		.O(O)
+	);
+endmodule
diff --git a/techlibs/ice40/ice40_opt.cc b/techlibs/ice40/ice40_opt.cc
index f528607d6..edb293b93 100644
--- a/techlibs/ice40/ice40_opt.cc
+++ b/techlibs/ice40/ice40_opt.cc
@@ -47,16 +47,20 @@ static void run_ice40_opts(Module *module)
 			continue;
 		}
 
-		if (cell->type == "\\SB_CARRY")
+		if (cell->type.in("\\SB_CARRY", "\\ICE40_CARRY_LUT"))
 		{
 			SigSpec non_const_inputs, replacement_output;
 			int count_zeros = 0, count_ones = 0;
 
 			SigBit inbit[3] = {
-				get_bit_or_zero(cell->getPort("\\I0")),
 				get_bit_or_zero(cell->getPort("\\I1")),
 				get_bit_or_zero(cell->getPort("\\CI"))
 			};
+			if (cell->type == "\\SB_CARRY")
+				inbit[2] = get_bit_or_zero(cell->getPort("\\I0"));
+			else if (cell->type == "\\ICE40_CARRY_LUT")
+				inbit[2] = get_bit_or_zero(cell->getPort("\\I2"));
+			else log_abort();
 			for (int i = 0; i < 3; i++)
 				if (inbit[i].wire == nullptr) {
 					if (inbit[i] == State::S1)
@@ -79,6 +83,14 @@ static void run_ice40_opts(Module *module)
 				module->design->scratchpad_set_bool("opt.did_something", true);
 				log("Optimized away SB_CARRY cell %s.%s: CO=%s\n",
 						log_id(module), log_id(cell), log_signal(replacement_output));
+
+				if (cell->type == "\\ICE40_CARRY_LUT")
+					module->addLut(NEW_ID,
+						{ RTLIL::S0, cell->getPort("\\I1"), cell->getPort("\\I2"), cell->getPort("\\CI") },
+						cell->getPort("\\O"),
+						RTLIL::Const("0110_1001_1001_0110"),
+						cell->get_src_attribute());
+
 				module->remove(cell);
 			}
 			continue;
diff --git a/techlibs/ice40/synth_ice40.cc b/techlibs/ice40/synth_ice40.cc
index 3faa10b4f..d09a1184c 100644
--- a/techlibs/ice40/synth_ice40.cc
+++ b/techlibs/ice40/synth_ice40.cc
@@ -296,7 +296,7 @@ struct SynthIce40Pass : public ScriptPass
 				run("opt_merge");
 				run(stringf("dff2dffe -unmap-mince %d", min_ce_use));
 			}
-			run("techmap -D NO_LUT -map +/ice40/cells_map.v");
+			run("techmap -D NO_LUT -D NO_CARRY -map +/ice40/cells_map.v");
 			run("opt_expr -mux_undef");
 			run("simplemap");
 			run("ice40_ffinit");