diff --git a/spec/std/crystal/compiler_rt/powidf2_spec.cr b/spec/std/crystal/compiler_rt/powidf2_spec.cr
new file mode 100644
index 000000000000..832c7a4bfa69
--- /dev/null
+++ b/spec/std/crystal/compiler_rt/powidf2_spec.cr
@@ -0,0 +1,94 @@
+require "spec"
+require "crystal/compiler_rt/pow"
+
+# Ported from https://github.com/llvm/llvm-project/blob/2e9df860468425645dcd1b241c5dbf76c072e314/compiler-rt/test/builtins/Unit/powidf2_test.c
+
+it ".__powidf2" do
+  __powidf2(0, 0).should eq 1
+  __powidf2(1, 0).should eq 1
+  __powidf2(1.5, 0).should eq 1
+  __powidf2(2, 0).should eq 1
+  __powidf2(Float64::INFINITY, 0).should eq 1
+  __powidf2(-0.0, 0).should eq 1
+  __powidf2(-1, 0).should eq 1
+  __powidf2(-1.5, 0).should eq 1
+  __powidf2(-2, 0).should eq 1
+  __powidf2(-Float64::INFINITY, 0).should eq 1
+  __powidf2(0, 1).should eq 0
+  __powidf2(0, 2).should eq 0
+  __powidf2(0, 3).should eq 0
+  __powidf2(0, 4).should eq 0
+  __powidf2(0, Int32::MAX - 1).should eq 0
+  __powidf2(0, Int32::MAX).should eq 0
+  __powidf2(-0.0, 1).should eq -0.0
+  __powidf2(-0.0, 2).should eq 0
+  __powidf2(-0.0, 3).should eq -0.0
+  __powidf2(-0.0, 4).should eq 0
+  __powidf2(-0.0, Int32::MAX - 1).should eq 0
+  __powidf2(-0.0, Int32::MAX).should eq -0.0
+  __powidf2(1, 1).should eq 1
+  __powidf2(1, 2).should eq 1
+  __powidf2(1, 3).should eq 1
+  __powidf2(1, 4).should eq 1
+  __powidf2(1, Int32::MAX - 1).should eq 1
+  __powidf2(1, Int32::MAX).should eq 1
+  __powidf2(Float64::INFINITY, 1).should eq Float64::INFINITY
+  __powidf2(Float64::INFINITY, 2).should eq Float64::INFINITY
+  __powidf2(Float64::INFINITY, 3).should eq Float64::INFINITY
+  __powidf2(Float64::INFINITY, 4).should eq Float64::INFINITY
+  __powidf2(Float64::INFINITY, Int32::MAX - 1).should eq Float64::INFINITY
+  __powidf2(Float64::INFINITY, Int32::MAX).should eq Float64::INFINITY
+  __powidf2(-Float64::INFINITY, 1).should eq -Float64::INFINITY
+  __powidf2(-Float64::INFINITY, 2).should eq Float64::INFINITY
+  __powidf2(-Float64::INFINITY, 3).should eq -Float64::INFINITY
+  __powidf2(-Float64::INFINITY, 4).should eq Float64::INFINITY
+  __powidf2(-Float64::INFINITY, Int32::MAX - 1).should eq Float64::INFINITY
+  __powidf2(-Float64::INFINITY, Int32::MAX).should eq -Float64::INFINITY
+  __powidf2(0, -1).should eq Float64::INFINITY
+  __powidf2(0, -2).should eq Float64::INFINITY
+  __powidf2(0, -3).should eq Float64::INFINITY
+  __powidf2(0, -4).should eq Float64::INFINITY
+  __powidf2(0, Int32::MIN + 2).should eq Float64::INFINITY
+  __powidf2(0, Int32::MIN + 1).should eq Float64::INFINITY
+  __powidf2(0, Int32::MIN).should eq Float64::INFINITY
+  __powidf2(-0.0, -1).should eq -Float64::INFINITY
+  __powidf2(-0.0, -2).should eq Float64::INFINITY
+  __powidf2(-0.0, -3).should eq -Float64::INFINITY
+  __powidf2(-0.0, -4).should eq Float64::INFINITY
+  __powidf2(-0.0, Int32::MIN + 2).should eq Float64::INFINITY
+  __powidf2(-0.0, Int32::MIN + 1).should eq -Float64::INFINITY
+  __powidf2(-0.0, Int32::MIN).should eq Float64::INFINITY
+  __powidf2(1, -1).should eq 1
+  __powidf2(1, -2).should eq 1
+  __powidf2(1, -3).should eq 1
+  __powidf2(1, -4).should eq 1
+  __powidf2(1, Int32::MIN + 2).should eq 1
+  __powidf2(1, Int32::MIN + 1).should eq 1
+  __powidf2(1, Int32::MIN).should eq 1
+  __powidf2(Float64::INFINITY, -1).should eq 0
+  __powidf2(Float64::INFINITY, -2).should eq 0
+  __powidf2(Float64::INFINITY, -3).should eq 0
+  __powidf2(Float64::INFINITY, -4).should eq 0
+  __powidf2(Float64::INFINITY, Int32::MIN + 2).should eq 0
+  __powidf2(Float64::INFINITY, Int32::MIN + 1).should eq 0
+  __powidf2(Float64::INFINITY, Int32::MIN).should eq 0
+  __powidf2(-Float64::INFINITY, -1).should eq -0.0
+  __powidf2(-Float64::INFINITY, -2).should eq 0
+  __powidf2(-Float64::INFINITY, -3).should eq -0.0
+  __powidf2(-Float64::INFINITY, -4).should eq 0
+  __powidf2(-Float64::INFINITY, Int32::MIN + 2).should eq 0
+  __powidf2(-Float64::INFINITY, Int32::MIN + 1).should eq -0.0
+  __powidf2(-Float64::INFINITY, Int32::MIN).should eq 0
+  __powidf2(2, 10).should eq 1024.0
+  __powidf2(-2, 10).should eq 1024.0
+  __powidf2(2, -10).should eq 1/1024.0
+  __powidf2(-2, -10).should eq 1/1024.0
+  __powidf2(2, 19).should eq 524288.0
+  __powidf2(-2, 19).should eq -524288.0
+  __powidf2(2, -19).should eq 1/524288.0
+  __powidf2(-2, -19).should eq -1/524288.0
+  __powidf2(2, 31).should eq 2147483648.0
+  __powidf2(-2, 31).should eq -2147483648.0
+  __powidf2(2, -31).should eq 1/2147483648.0
+  __powidf2(-2, -31).should eq -1/2147483648.0
+end
diff --git a/spec/std/crystal/compiler_rt/powisf2_spec.cr b/spec/std/crystal/compiler_rt/powisf2_spec.cr
new file mode 100644
index 000000000000..aaad225be2d2
--- /dev/null
+++ b/spec/std/crystal/compiler_rt/powisf2_spec.cr
@@ -0,0 +1,94 @@
+require "spec"
+require "crystal/compiler_rt/pow"
+
+# Ported from https://github.com/llvm/llvm-project/blob/2e9df860468425645dcd1b241c5dbf76c072e314/compiler-rt/test/builtins/Unit/powisf2_test.c
+
+it ".__powisf2" do
+  __powisf2(0, 0).should eq 1
+  __powisf2(1, 0).should eq 1
+  __powisf2(1.5, 0).should eq 1
+  __powisf2(2, 0).should eq 1
+  __powisf2(Float32::INFINITY, 0).should eq 1
+  __powisf2(-0.0, 0).should eq 1
+  __powisf2(-1, 0).should eq 1
+  __powisf2(-1.5, 0).should eq 1
+  __powisf2(-2, 0).should eq 1
+  __powisf2(-Float32::INFINITY, 0).should eq 1
+  __powisf2(0, 1).should eq 0
+  __powisf2(0, 2).should eq 0
+  __powisf2(0, 3).should eq 0
+  __powisf2(0, 4).should eq 0
+  __powisf2(0, Int32::MAX - 1).should eq 0
+  __powisf2(0, Int32::MAX).should eq 0
+  __powisf2(-0.0, 1).should eq -0.0
+  __powisf2(-0.0, 2).should eq 0
+  __powisf2(-0.0, 3).should eq -0.0
+  __powisf2(-0.0, 4).should eq 0
+  __powisf2(-0.0, Int32::MAX - 1).should eq 0
+  __powisf2(-0.0, Int32::MAX).should eq -0.0
+  __powisf2(1, 1).should eq 1
+  __powisf2(1, 2).should eq 1
+  __powisf2(1, 3).should eq 1
+  __powisf2(1, 4).should eq 1
+  __powisf2(1, Int32::MAX - 1).should eq 1
+  __powisf2(1, Int32::MAX).should eq 1
+  __powisf2(Float32::INFINITY, 1).should eq Float32::INFINITY
+  __powisf2(Float32::INFINITY, 2).should eq Float32::INFINITY
+  __powisf2(Float32::INFINITY, 3).should eq Float32::INFINITY
+  __powisf2(Float32::INFINITY, 4).should eq Float32::INFINITY
+  __powisf2(Float32::INFINITY, Int32::MAX - 1).should eq Float32::INFINITY
+  __powisf2(Float32::INFINITY, Int32::MAX).should eq Float32::INFINITY
+  __powisf2(-Float32::INFINITY, 1).should eq -Float32::INFINITY
+  __powisf2(-Float32::INFINITY, 2).should eq Float32::INFINITY
+  __powisf2(-Float32::INFINITY, 3).should eq -Float32::INFINITY
+  __powisf2(-Float32::INFINITY, 4).should eq Float32::INFINITY
+  __powisf2(-Float32::INFINITY, Int32::MAX - 1).should eq Float32::INFINITY
+  __powisf2(-Float32::INFINITY, Int32::MAX).should eq -Float32::INFINITY
+  __powisf2(0, -1).should eq Float32::INFINITY
+  __powisf2(0, -2).should eq Float32::INFINITY
+  __powisf2(0, -3).should eq Float32::INFINITY
+  __powisf2(0, -4).should eq Float32::INFINITY
+  __powisf2(0, Int32::MIN + 2).should eq Float32::INFINITY
+  __powisf2(0, Int32::MIN + 1).should eq Float32::INFINITY
+  __powisf2(0, Int32::MIN).should eq Float32::INFINITY
+  __powisf2(-0.0, -1).should eq -Float32::INFINITY
+  __powisf2(-0.0, -2).should eq Float32::INFINITY
+  __powisf2(-0.0, -3).should eq -Float32::INFINITY
+  __powisf2(-0.0, -4).should eq Float32::INFINITY
+  __powisf2(-0.0, Int32::MIN + 2).should eq Float32::INFINITY
+  __powisf2(-0.0, Int32::MIN + 1).should eq -Float32::INFINITY
+  __powisf2(-0.0, Int32::MIN).should eq Float32::INFINITY
+  __powisf2(1, -1).should eq 1
+  __powisf2(1, -2).should eq 1
+  __powisf2(1, -3).should eq 1
+  __powisf2(1, -4).should eq 1
+  __powisf2(1, Int32::MIN + 2).should eq 1
+  __powisf2(1, Int32::MIN + 1).should eq 1
+  __powisf2(1, Int32::MIN).should eq 1
+  __powisf2(Float32::INFINITY, -1).should eq 0
+  __powisf2(Float32::INFINITY, -2).should eq 0
+  __powisf2(Float32::INFINITY, -3).should eq 0
+  __powisf2(Float32::INFINITY, -4).should eq 0
+  __powisf2(Float32::INFINITY, Int32::MIN + 2).should eq 0
+  __powisf2(Float32::INFINITY, Int32::MIN + 1).should eq 0
+  __powisf2(Float32::INFINITY, Int32::MIN).should eq 0
+  __powisf2(-Float32::INFINITY, -1).should eq -0.0
+  __powisf2(-Float32::INFINITY, -2).should eq 0
+  __powisf2(-Float32::INFINITY, -3).should eq -0.0
+  __powisf2(-Float32::INFINITY, -4).should eq 0
+  __powisf2(-Float32::INFINITY, Int32::MIN + 2).should eq 0
+  __powisf2(-Float32::INFINITY, Int32::MIN + 1).should eq -0.0
+  __powisf2(-Float32::INFINITY, Int32::MIN).should eq 0
+  __powisf2(2, 10).should eq 1024.0
+  __powisf2(-2, 10).should eq 1024.0
+  __powisf2(2, -10).should eq 1/1024.0
+  __powisf2(-2, -10).should eq 1/1024.0
+  __powisf2(2, 19).should eq 524288.0
+  __powisf2(-2, 19).should eq -524288.0
+  __powisf2(2, -19).should eq 1/524288.0
+  __powisf2(-2, -19).should eq -1/524288.0
+  __powisf2(2, 31).should eq 2147483648.0
+  __powisf2(-2, 31).should eq -2147483648.0
+  __powisf2(2, -31).should eq 1/2147483648.0
+  __powisf2(-2, -31).should eq -1/2147483648.0
+end
diff --git a/src/crystal/compiler_rt.cr b/src/crystal/compiler_rt.cr
index b96a61e9fe1f..e1681dac4186 100644
--- a/src/crystal/compiler_rt.cr
+++ b/src/crystal/compiler_rt.cr
@@ -11,8 +11,11 @@ require "./compiler_rt/divmod128.cr"
 {% end %}
 
 {% if flag?(:wasm32) %}
-  # __ashlti3, __ashrti3 and __lshrti3 were only missing on wasm32
+  # __ashlti3, __ashrti3 and __lshrti3 are missing on wasm32
   require "./compiler_rt/shift.cr"
+
+  # __powisf2 and __powidf2 are missing on wasm32
+  require "./compiler_rt/pow.cr"
 {% end %}
 
 {% if flag?(:win32) && flag?(:bits64) %}
diff --git a/src/crystal/compiler_rt/pow.cr b/src/crystal/compiler_rt/pow.cr
new file mode 100644
index 000000000000..dcbc29cf3211
--- /dev/null
+++ b/src/crystal/compiler_rt/pow.cr
@@ -0,0 +1,20 @@
+private macro __pow_impl(name, one, float_type)
+  # :nodoc:
+  # Ported from https://github.com/llvm/llvm-project/blob/2e9df860468425645dcd1b241c5dbf76c072e314/compiler-rt/lib/builtins
+  fun {{name}}(a : {{float_type}}, b : Int32) : {{float_type}}
+    recip = b < 0
+    r = {{one}}
+
+    loop do
+      r *= a if b & 1 != 0
+      b = b.unsafe_div 2
+      break if b == 0
+      a *= a
+    end
+
+    recip ? 1 / r : r
+  end
+end
+
+__pow_impl(__powisf2, 1f32, Float32)
+__pow_impl(__powidf2, 1f64, Float64)