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:
Jonas Maebe 2023-01-01 12:09:43 +01:00
parent ee0ad3ff86
commit ab581c5c30
5 changed files with 38 additions and 8 deletions

View File

@ -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

View File

@ -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;

View File

@ -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 }

View File

@ -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 }

View File

@ -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],