mirror of
https://gitlab.com/freepascal.org/fpc/source.git
synced 2025-04-05 14:24:24 +02:00
LLVM: override thlcgobj.g_undefined_ok
Uses the freeze instruction available in LLVM 10.0+. If we don't freeze undef/ poison values before using them in a calculation (even if that calculation is something like "and 0", which masks the result completely), the result will still be undef/poison and will keep propagating.
This commit is contained in:
parent
ee0ad3ff86
commit
ab581c5c30
@ -57,6 +57,8 @@ interface
|
|||||||
{ e.g. dst = alloca size }
|
{ e.g. dst = alloca size }
|
||||||
constructor op_ref_size(op:tllvmop;const dst:treference;size:tdef);
|
constructor op_ref_size(op:tllvmop;const dst:treference;size:tdef);
|
||||||
|
|
||||||
|
{ e.g. dst = freeze size src }
|
||||||
|
constructor op_reg_size_reg(op:tllvmop;dst:tregister;size:tdef;src:tregister);
|
||||||
{ e.g. dst = add size src1, src2 }
|
{ e.g. dst = add size src1, src2 }
|
||||||
constructor op_reg_size_reg_reg(op:tllvmop;dst:tregister;size:tdef;src1,src2:tregister);
|
constructor op_reg_size_reg_reg(op:tllvmop;dst:tregister;size:tdef;src1,src2:tregister);
|
||||||
{ e.g. dst = shl size src1, 1 ( = src1 shl 1) }
|
{ e.g. dst = shl size src1, 1 ( = src1 shl 1) }
|
||||||
@ -637,7 +639,8 @@ implementation
|
|||||||
la_load,
|
la_load,
|
||||||
la_icmp, la_fcmp,
|
la_icmp, la_fcmp,
|
||||||
la_phi, la_select,
|
la_phi, la_select,
|
||||||
la_va_arg, la_landingpad:
|
la_va_arg, la_landingpad,
|
||||||
|
la_freeze:
|
||||||
begin
|
begin
|
||||||
if opnr=0 then
|
if opnr=0 then
|
||||||
result:=operand_write
|
result:=operand_write
|
||||||
@ -855,6 +858,17 @@ implementation
|
|||||||
end;
|
end;
|
||||||
|
|
||||||
|
|
||||||
|
{ %dst = freeze i32 %src }
|
||||||
|
constructor taillvm.op_reg_size_reg(op: tllvmop; dst: tregister; size: tdef; src: tregister);
|
||||||
|
begin
|
||||||
|
create_llvm(op);
|
||||||
|
ops:=3;
|
||||||
|
loadreg(0,dst);
|
||||||
|
loaddef(1,size);
|
||||||
|
loadreg(2,src);
|
||||||
|
end;
|
||||||
|
|
||||||
|
|
||||||
{ %dst = add i32 %src1, %src2 }
|
{ %dst = add i32 %src1, %src2 }
|
||||||
constructor taillvm.op_reg_size_reg_reg(op: tllvmop; dst: tregister;size: tdef; src1, src2: tregister);
|
constructor taillvm.op_reg_size_reg_reg(op: tllvmop; dst: tregister;size: tdef; src1, src2: tregister);
|
||||||
begin
|
begin
|
||||||
|
@ -98,6 +98,8 @@ uses
|
|||||||
|
|
||||||
procedure g_concatcopy(list : TAsmList;size: tdef; const source,dest : treference);override;
|
procedure g_concatcopy(list : TAsmList;size: tdef; const source,dest : treference);override;
|
||||||
|
|
||||||
|
procedure g_undefined_ok(list: TAsmList; size: tdef; reg: tregister); override;
|
||||||
|
|
||||||
procedure a_loadfpu_ref_reg(list: TAsmList; fromsize, tosize: tdef; const ref: treference; reg: tregister); override;
|
procedure a_loadfpu_ref_reg(list: TAsmList; fromsize, tosize: tdef; const ref: treference; reg: tregister); override;
|
||||||
procedure a_loadfpu_reg_ref(list: TAsmList; fromsize, tosize: tdef; reg: tregister; const ref: treference); override;
|
procedure a_loadfpu_reg_ref(list: TAsmList; fromsize, tosize: tdef; reg: tregister; const ref: treference); override;
|
||||||
procedure a_loadfpu_reg_reg(list: TAsmList; fromsize, tosize: tdef; reg1, reg2: tregister); override;
|
procedure a_loadfpu_reg_reg(list: TAsmList; fromsize, tosize: tdef; reg1, reg2: tregister); override;
|
||||||
@ -1319,6 +1321,17 @@ implementation
|
|||||||
end;
|
end;
|
||||||
|
|
||||||
|
|
||||||
|
procedure thlcgllvm.g_undefined_ok(list: TAsmList; size: tdef; reg: tregister);
|
||||||
|
begin
|
||||||
|
if not(llvmflag_no_freeze in llvmversion_properties[current_settings.llvmversion]) then
|
||||||
|
begin
|
||||||
|
list.concat(taillvm.op_reg_size_reg(la_freeze,reg,size,reg));
|
||||||
|
exit;
|
||||||
|
end;
|
||||||
|
internalerror(2023010110);
|
||||||
|
end;
|
||||||
|
|
||||||
|
|
||||||
procedure thlcgllvm.a_loadfpu_ref_reg(list: TAsmList; fromsize, tosize: tdef; const ref: treference; reg: tregister);
|
procedure thlcgllvm.a_loadfpu_ref_reg(list: TAsmList; fromsize, tosize: tdef; const ref: treference; reg: tregister);
|
||||||
var
|
var
|
||||||
tmpreg: tregister;
|
tmpreg: tregister;
|
||||||
|
@ -58,6 +58,7 @@ interface
|
|||||||
'phi', 'select', 'call',
|
'phi', 'select', 'call',
|
||||||
'va_arg', 'landingpad',
|
'va_arg', 'landingpad',
|
||||||
'blockaddress',
|
'blockaddress',
|
||||||
|
'freeze',
|
||||||
{ fpc pseudo opcodes }
|
{ fpc pseudo opcodes }
|
||||||
'type', { type definition }
|
'type', { type definition }
|
||||||
'catch', { catch exception }
|
'catch', { catch exception }
|
||||||
|
@ -66,6 +66,7 @@ interface
|
|||||||
la_phi, la_select, la_call,
|
la_phi, la_select, la_call,
|
||||||
la_va_arg, la_landingpad,
|
la_va_arg, la_landingpad,
|
||||||
la_blockaddress,
|
la_blockaddress,
|
||||||
|
la_freeze,
|
||||||
{ fpc pseudo opcodes }
|
{ fpc pseudo opcodes }
|
||||||
la_type, { type definition }
|
la_type, { type definition }
|
||||||
la_catch, { catch clause of a landingpad }
|
la_catch, { catch clause of a landingpad }
|
||||||
|
@ -72,7 +72,8 @@ type
|
|||||||
llvmflag_para_attr_type, { parameter attributes such as noalias and byval need to repeat the type }
|
llvmflag_para_attr_type, { parameter attributes such as noalias and byval need to repeat the type }
|
||||||
llvmflag_opaque_ptr_transition, { initial opaque pointer introduction, needs to some elementtype attributes }
|
llvmflag_opaque_ptr_transition, { initial opaque pointer introduction, needs to some elementtype attributes }
|
||||||
llvmflag_opaque_ptr, { only opaque pointers }
|
llvmflag_opaque_ptr, { only opaque pointers }
|
||||||
llvmflag_sanitizer_attributes { can use attributes to exclude symbols from sanitizers }
|
llvmflag_sanitizer_attributes, { can use attributes to exclude symbols from sanitizers }
|
||||||
|
llvmflag_no_freeze { lacks the freeze opcode to clear undefined/poison values }
|
||||||
);
|
);
|
||||||
tllvmversionflags = set of tllvmversionflag;
|
tllvmversionflags = set of tllvmversionflag;
|
||||||
|
|
||||||
@ -124,12 +125,12 @@ Const
|
|||||||
llvmversion_properties: array[tllvmversion] of tllvmversionflags =
|
llvmversion_properties: array[tllvmversion] of tllvmversionflags =
|
||||||
(
|
(
|
||||||
{ invalid } [],
|
{ invalid } [],
|
||||||
{ llvmver_7_0 } [llvmflag_memcpy_indiv_align,llvmflag_null_pointer_valid,llvmflag_NoDISPFlags],
|
{ llvmver_7_0 } [llvmflag_memcpy_indiv_align,llvmflag_null_pointer_valid,llvmflag_NoDISPFlags,llvmflag_no_freeze],
|
||||||
{ llvmver_7_1 } [llvmflag_memcpy_indiv_align,llvmflag_null_pointer_valid,llvmflag_NoDISPFlags],
|
{ llvmver_7_1 } [llvmflag_memcpy_indiv_align,llvmflag_null_pointer_valid,llvmflag_NoDISPFlags,llvmflag_no_freeze],
|
||||||
{ llvmver_8_0 } [llvmflag_memcpy_indiv_align,llvmflag_null_pointer_valid,llvmflag_NoDISPFlagMainSubprogram],
|
{ llvmver_8_0 } [llvmflag_memcpy_indiv_align,llvmflag_null_pointer_valid,llvmflag_NoDISPFlagMainSubprogram,llvmflag_no_freeze],
|
||||||
{ llvmver_xc_11 } [llvmflag_memcpy_indiv_align,llvmflag_null_pointer_valid,llvmflag_NoDISPFlagMainSubprogram],
|
{ llvmver_xc_11 } [llvmflag_memcpy_indiv_align,llvmflag_null_pointer_valid,llvmflag_NoDISPFlagMainSubprogram,llvmflag_no_freeze],
|
||||||
{ llvmver_9_0 } [llvmflag_memcpy_indiv_align,llvmflag_null_pointer_valid,llvmflag_constrained_fptrunc_fpext],
|
{ llvmver_9_0 } [llvmflag_memcpy_indiv_align,llvmflag_null_pointer_valid,llvmflag_constrained_fptrunc_fpext,llvmflag_no_freeze],
|
||||||
{ llvmver_xc_11_4 } [llvmflag_memcpy_indiv_align,llvmflag_null_pointer_valid,llvmflag_constrained_fptrunc_fpext],
|
{ llvmver_xc_11_4 } [llvmflag_memcpy_indiv_align,llvmflag_null_pointer_valid,llvmflag_constrained_fptrunc_fpext,llvmflag_no_freeze],
|
||||||
{ llvmver_10_0 } [llvmflag_memcpy_indiv_align,llvmflag_null_pointer_valid,llvmflag_constrained_fptrunc_fpext,llvmflag_constrained_fptoi_itofp],
|
{ llvmver_10_0 } [llvmflag_memcpy_indiv_align,llvmflag_null_pointer_valid,llvmflag_constrained_fptrunc_fpext,llvmflag_constrained_fptoi_itofp],
|
||||||
{ llvmver_xc_12_0 } [llvmflag_memcpy_indiv_align,llvmflag_null_pointer_valid,llvmflag_constrained_fptrunc_fpext,llvmflag_constrained_fptoi_itofp],
|
{ llvmver_xc_12_0 } [llvmflag_memcpy_indiv_align,llvmflag_null_pointer_valid,llvmflag_constrained_fptrunc_fpext,llvmflag_constrained_fptoi_itofp],
|
||||||
{ llvmver_11_0 } [llvmflag_memcpy_indiv_align,llvmflag_null_pointer_valid_new,llvmflag_constrained_fptrunc_fpext,llvmflag_constrained_fptoi_itofp,llvmflag_array_datalocation],
|
{ llvmver_11_0 } [llvmflag_memcpy_indiv_align,llvmflag_null_pointer_valid_new,llvmflag_constrained_fptrunc_fpext,llvmflag_constrained_fptoi_itofp,llvmflag_array_datalocation],
|
||||||
|
Loading…
Reference in New Issue
Block a user