BRepAlgoAPI_Fuse returns a wrong result

I've made a prism by BRepPrimAPI_MakePrism with a circle face as base shape. It should be a cylinder. (see p1.png)
And I've made a solid pipe by BRepOffsetAPI_MakePipeShell, with a ellipse to call BRepOffsetAPI_MakePipeShell::Add and a B spline curve as spine. (see p2.png)
Then I use BRepAlgoAPI_Fuse to combine those above two shapes. Half of the pipe loses. (see p3.png)
Do I make a mistake? Or is it a bug?

My code is following:

BRepPrimAPI_MakePrism prism(
BRepBuilderAPI_MakeFace(
BRepBuilderAPI_MakeWire(
BRepBuilderAPI_MakeEdge(
GC_MakeCircle(gp_Pnt(0, 0, 0), gp_Dir(0, 0, 1), 100).Value()
)
)
),
gp_Vec(0, 0, 400)
);
BRepBuilderAPI_MakeWire w1(
BRepBuilderAPI_MakeEdge(
GC_MakeEllipse(gp_Pnt(-400, 100, 0), gp_Pnt(-480, 0, 0), gp_Pnt(-400, 0, 0)).Value()
)
);
auto curve = []()->Handle(Geom_BSplineCurve) {
TColgp_Array1OfPnt poles(1, 4);
poles.SetValue(1, gp_Pnt(-400, 0, 0));
poles.SetValue(2, gp_Pnt(-400, 0, 400));
poles.SetValue(3, gp_Pnt(400, 0, 400));
poles.SetValue(4, gp_Pnt(400, 0, 0));
TColStd_Array1OfReal knots(1, 2);
knots.SetValue(1, 0);
knots.SetValue(2, 1);
TColStd_Array1OfInteger mults(1, 2);
mults.SetValue(1, 4);
mults.SetValue(2, 4);
int degree = 3;
return new Geom_BSplineCurve(poles, knots, mults, degree);
}();
BRepBuilderAPI_MakeWire w(
BRepBuilderAPI_MakeEdge(curve).Edge()
);
BRepOffsetAPI_MakePipeShell pipe(w);
pipe.Add(w1);
pipe.SetMode(true);
pipe.SetTransitionMode(BRepBuilderAPI_TransitionMode::BRepBuilderAPI_RightCorner);
pipe.Build();
pipe.MakeSolid();
BRepAlgoAPI_Fuse f20(pipe, prism); // f20 returns wrong shape obviously

Attachments: