Skip to content

Commit a4ac1f9

Browse files
JeffBezansonvchuravy
authored andcommitted
fix #37880, overflow in shift amount range check in codegen (#37891)
(cherry picked from commit 0a04f41)
1 parent b9ba10a commit a4ac1f9

File tree

1 file changed

+39
-19
lines changed

1 file changed

+39
-19
lines changed

src/intrinsics.cpp

Lines changed: 39 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -1186,25 +1186,45 @@ static Value *emit_untyped_intrinsic(jl_codectx_t &ctx, intrinsic f, Value **arg
11861186
case or_int: return ctx.builder.CreateOr(x, y);
11871187
case xor_int: return ctx.builder.CreateXor(x, y);
11881188

1189-
case shl_int:
1190-
return ctx.builder.CreateSelect(
1191-
ctx.builder.CreateICmpUGE(y, ConstantInt::get(y->getType(),
1192-
t->getPrimitiveSizeInBits())),
1193-
ConstantInt::get(t, 0),
1194-
ctx.builder.CreateShl(x, uint_cnvt(ctx, t, y)));
1195-
case lshr_int:
1196-
return ctx.builder.CreateSelect(
1197-
ctx.builder.CreateICmpUGE(y, ConstantInt::get(y->getType(),
1198-
t->getPrimitiveSizeInBits())),
1199-
ConstantInt::get(t, 0),
1200-
ctx.builder.CreateLShr(x, uint_cnvt(ctx, t, y)));
1201-
case ashr_int:
1202-
return ctx.builder.CreateSelect(
1203-
ctx.builder.CreateICmpUGE(y, ConstantInt::get(y->getType(),
1204-
t->getPrimitiveSizeInBits())),
1205-
ctx.builder.CreateAShr(x, ConstantInt::get(t, t->getPrimitiveSizeInBits() - 1)),
1206-
ctx.builder.CreateAShr(x, uint_cnvt(ctx, t, y)));
1207-
1189+
case shl_int: {
1190+
Value *the_shl = ctx.builder.CreateShl(x, uint_cnvt(ctx, t, y));
1191+
if (ConstantInt::isValueValidForType(y->getType(), (uint64_t)t->getPrimitiveSizeInBits())) {
1192+
return ctx.builder.CreateSelect(
1193+
ctx.builder.CreateICmpUGE(y, ConstantInt::get(y->getType(),
1194+
t->getPrimitiveSizeInBits())),
1195+
ConstantInt::get(t, 0),
1196+
the_shl);
1197+
}
1198+
else {
1199+
return the_shl;
1200+
}
1201+
}
1202+
case lshr_int: {
1203+
Value *the_shr = ctx.builder.CreateLShr(x, uint_cnvt(ctx, t, y));
1204+
if (ConstantInt::isValueValidForType(y->getType(), (uint64_t)t->getPrimitiveSizeInBits())) {
1205+
return ctx.builder.CreateSelect(
1206+
ctx.builder.CreateICmpUGE(y, ConstantInt::get(y->getType(),
1207+
t->getPrimitiveSizeInBits())),
1208+
ConstantInt::get(t, 0),
1209+
the_shr);
1210+
}
1211+
else {
1212+
return the_shr;
1213+
}
1214+
}
1215+
case ashr_int: {
1216+
Value *the_shr = ctx.builder.CreateAShr(x, uint_cnvt(ctx, t, y));
1217+
if (ConstantInt::isValueValidForType(y->getType(), (uint64_t)t->getPrimitiveSizeInBits())) {
1218+
return ctx.builder.CreateSelect(
1219+
ctx.builder.CreateICmpUGE(y, ConstantInt::get(y->getType(),
1220+
t->getPrimitiveSizeInBits())),
1221+
ctx.builder.CreateAShr(x, ConstantInt::get(t, t->getPrimitiveSizeInBits() - 1)),
1222+
the_shr);
1223+
}
1224+
else {
1225+
return the_shr;
1226+
}
1227+
}
12081228
case bswap_int: {
12091229
FunctionCallee bswapintr = Intrinsic::getDeclaration(jl_Module, Intrinsic::bswap, makeArrayRef(t));
12101230
return ctx.builder.CreateCall(bswapintr, x);

0 commit comments

Comments
 (0)