diff --git a/src/codegen/expressions/access/index.ts b/src/codegen/expressions/access/index.ts index 792ae3fc..d1113300 100644 --- a/src/codegen/expressions/access/index.ts +++ b/src/codegen/expressions/access/index.ts @@ -201,6 +201,9 @@ export class IndexAccessGenerator { this.ctx.emit(`call void @__cs_bounds_fail(i32 ${index}, i32 ${len})`); this.ctx.emit(`unreachable`); this.ctx.emit(`${okLabel}:`); + const inBounds = this.ctx.nextTemp(); + this.ctx.emit(`${inBounds} = icmp ult i32 ${index}, ${len}`); + this.ctx.emit(`call void @llvm.assume(i1 ${inBounds})`); } private generateStringArrayIndex(expr: IndexAccessNode, params: string[]): string { diff --git a/src/codegen/expressions/operators/binary.ts b/src/codegen/expressions/operators/binary.ts index 860a612a..17dac293 100644 --- a/src/codegen/expressions/operators/binary.ts +++ b/src/codegen/expressions/operators/binary.ts @@ -88,12 +88,12 @@ export class BinaryExpressionGenerator { const leftValue = this.ctx.generateExpression(left, params); const rightValue = this.ctx.generateExpression(right, params); - // Arithmetic operators (floating-point) + // Arithmetic operators (floating-point) — fast-math flags enable LLVM optimizations const arithMap: { [key: string]: string } = { - "+": "fadd nsz arcp contract reassoc afn", - "-": "fsub nsz arcp contract reassoc afn", - "*": "fmul nsz arcp contract reassoc afn", - "/": "fdiv nsz arcp contract reassoc afn", + "+": "fadd nnan ninf nsz arcp contract reassoc afn", + "-": "fsub nnan ninf nsz arcp contract reassoc afn", + "*": "fmul nnan ninf nsz arcp contract reassoc afn", + "/": "fdiv nnan ninf nsz arcp contract reassoc afn", }; // Bitwise operators (need to convert double -> i64 -> operate -> double) diff --git a/src/codegen/infrastructure/ir-builders.ts b/src/codegen/infrastructure/ir-builders.ts index 81eaef00..5f80b40f 100644 --- a/src/codegen/infrastructure/ir-builders.ts +++ b/src/codegen/infrastructure/ir-builders.ts @@ -25,30 +25,32 @@ export function emitMul(ctx: EmitContext, type: string, lhs: string, rhs: string return temp; } +const FMATH = "nnan ninf nsz arcp contract reassoc afn"; + export function emitFAdd(ctx: EmitContext, lhs: string, rhs: string): string { const temp = ctx.nextTemp(); - ctx.emit(`${temp} = fadd double ${lhs}, ${rhs}`); + ctx.emit(`${temp} = fadd ${FMATH} double ${lhs}, ${rhs}`); ctx.setVariableType(temp, "double"); return temp; } export function emitFSub(ctx: EmitContext, lhs: string, rhs: string): string { const temp = ctx.nextTemp(); - ctx.emit(`${temp} = fsub double ${lhs}, ${rhs}`); + ctx.emit(`${temp} = fsub ${FMATH} double ${lhs}, ${rhs}`); ctx.setVariableType(temp, "double"); return temp; } export function emitFMul(ctx: EmitContext, lhs: string, rhs: string): string { const temp = ctx.nextTemp(); - ctx.emit(`${temp} = fmul double ${lhs}, ${rhs}`); + ctx.emit(`${temp} = fmul ${FMATH} double ${lhs}, ${rhs}`); ctx.setVariableType(temp, "double"); return temp; } export function emitFDiv(ctx: EmitContext, lhs: string, rhs: string): string { const temp = ctx.nextTemp(); - ctx.emit(`${temp} = fdiv double ${lhs}, ${rhs}`); + ctx.emit(`${temp} = fdiv ${FMATH} double ${lhs}, ${rhs}`); ctx.setVariableType(temp, "double"); return temp; } @@ -62,14 +64,14 @@ export function emitSRem(ctx: EmitContext, type: string, lhs: string, rhs: strin export function emitFRem(ctx: EmitContext, lhs: string, rhs: string): string { const temp = ctx.nextTemp(); - ctx.emit(`${temp} = frem double ${lhs}, ${rhs}`); + ctx.emit(`${temp} = frem ${FMATH} double ${lhs}, ${rhs}`); ctx.setVariableType(temp, "double"); return temp; } export function emitFNeg(ctx: EmitContext, value: string): string { const temp = ctx.nextTemp(); - ctx.emit(`${temp} = fneg double ${value}`); + ctx.emit(`${temp} = fneg ${FMATH} double ${value}`); ctx.setVariableType(temp, "double"); return temp; } diff --git a/src/codegen/infrastructure/llvm-declarations.ts b/src/codegen/infrastructure/llvm-declarations.ts index 8a3935c3..8986b829 100644 --- a/src/codegen/infrastructure/llvm-declarations.ts +++ b/src/codegen/infrastructure/llvm-declarations.ts @@ -51,6 +51,7 @@ export function getLLVMDeclarations(config?: DeclConfig): string { ir += "declare i8* @strstr(i8*, i8*)\n"; ir += "declare i8* @strchr(i8*, i32)\n"; ir += "declare i8* @strrchr(i8*, i32)\n"; + ir += "declare void @llvm.assume(i1)\n"; ir += "declare void @llvm.memcpy.p0i8.p0i8.i64(i8*, i8*, i64, i1)\n"; ir += "declare void @llvm.memmove.p0i8.p0i8.i64(i8*, i8*, i64, i1)\n"; ir += "declare void @llvm.memset.p0i8.i64(i8*, i8, i64, i1)\n";