Skip to content

Commit d54fbb9

Browse files
committed
Auto merge of #87695 - tmiasko:gep-opaque-pointers, r=nagisa
Prepare GEP building for opaque pointers
2 parents 6fe0886 + 8e0df32 commit d54fbb9

File tree

14 files changed

+110
-46
lines changed

14 files changed

+110
-46
lines changed

compiler/rustc_codegen_llvm/src/builder.rs

+20-8
Original file line numberDiff line numberDiff line change
@@ -497,9 +497,10 @@ impl BuilderMethods<'a, 'tcx> for Builder<'a, 'll, 'tcx> {
497497
OperandValue::Immediate(self.to_immediate(llval, place.layout))
498498
} else if let abi::Abi::ScalarPair(ref a, ref b) = place.layout.abi {
499499
let b_offset = a.value.size(self).align_to(b.value.align(self).abi);
500+
let pair_ty = place.layout.llvm_type(self);
500501

501502
let mut load = |i, scalar: &abi::Scalar, align| {
502-
let llptr = self.struct_gep(place.llval, i as u64);
503+
let llptr = self.struct_gep(pair_ty, place.llval, i as u64);
503504
let llty = place.layout.scalar_pair_element_llvm_type(self, i, false);
504505
let load = self.load(llty, llptr, align);
505506
scalar_load_metadata(self, load, scalar);
@@ -543,7 +544,11 @@ impl BuilderMethods<'a, 'tcx> for Builder<'a, 'll, 'tcx> {
543544
.val
544545
.store(&mut body_bx, PlaceRef::new_sized_aligned(current, cg_elem.layout, align));
545546

546-
let next = body_bx.inbounds_gep(current, &[self.const_usize(1)]);
547+
let next = body_bx.inbounds_gep(
548+
self.backend_type(cg_elem.layout),
549+
current,
550+
&[self.const_usize(1)],
551+
);
547552
body_bx.br(header_bx.llbb());
548553
header_bx.add_incoming_to_phi(current, next, body_bx.llbb());
549554

@@ -639,10 +644,11 @@ impl BuilderMethods<'a, 'tcx> for Builder<'a, 'll, 'tcx> {
639644
}
640645
}
641646

642-
fn gep(&mut self, ptr: &'ll Value, indices: &[&'ll Value]) -> &'ll Value {
647+
fn gep(&mut self, ty: &'ll Type, ptr: &'ll Value, indices: &[&'ll Value]) -> &'ll Value {
643648
unsafe {
644-
llvm::LLVMBuildGEP(
649+
llvm::LLVMBuildGEP2(
645650
self.llbuilder,
651+
ty,
646652
ptr,
647653
indices.as_ptr(),
648654
indices.len() as c_uint,
@@ -651,10 +657,16 @@ impl BuilderMethods<'a, 'tcx> for Builder<'a, 'll, 'tcx> {
651657
}
652658
}
653659

654-
fn inbounds_gep(&mut self, ptr: &'ll Value, indices: &[&'ll Value]) -> &'ll Value {
660+
fn inbounds_gep(
661+
&mut self,
662+
ty: &'ll Type,
663+
ptr: &'ll Value,
664+
indices: &[&'ll Value],
665+
) -> &'ll Value {
655666
unsafe {
656-
llvm::LLVMBuildInBoundsGEP(
667+
llvm::LLVMBuildInBoundsGEP2(
657668
self.llbuilder,
669+
ty,
658670
ptr,
659671
indices.as_ptr(),
660672
indices.len() as c_uint,
@@ -663,9 +675,9 @@ impl BuilderMethods<'a, 'tcx> for Builder<'a, 'll, 'tcx> {
663675
}
664676
}
665677

666-
fn struct_gep(&mut self, ptr: &'ll Value, idx: u64) -> &'ll Value {
678+
fn struct_gep(&mut self, ty: &'ll Type, ptr: &'ll Value, idx: u64) -> &'ll Value {
667679
assert_eq!(idx as c_uint as u64, idx);
668-
unsafe { llvm::LLVMBuildStructGEP(self.llbuilder, ptr, idx as c_uint, UNNAMED) }
680+
unsafe { llvm::LLVMBuildStructGEP2(self.llbuilder, ty, ptr, idx as c_uint, UNNAMED) }
669681
}
670682

671683
/* Casts */

compiler/rustc_codegen_llvm/src/common.rs

+4-2
Original file line numberDiff line numberDiff line change
@@ -268,7 +268,8 @@ impl ConstMethods<'tcx> for CodegenCx<'ll, 'tcx> {
268268
}
269269
};
270270
let llval = unsafe {
271-
llvm::LLVMConstInBoundsGEP(
271+
llvm::LLVMRustConstInBoundsGEP2(
272+
self.type_i8(),
272273
self.const_bitcast(base_addr, self.type_i8p_ext(base_addr_space)),
273274
&self.const_usize(offset.bytes()),
274275
1,
@@ -303,7 +304,8 @@ impl ConstMethods<'tcx> for CodegenCx<'ll, 'tcx> {
303304
let base_addr = self.static_addr_of(init, alloc.align, None);
304305

305306
let llval = unsafe {
306-
llvm::LLVMConstInBoundsGEP(
307+
llvm::LLVMRustConstInBoundsGEP2(
308+
self.type_i8(),
307309
self.const_bitcast(base_addr, self.type_i8p()),
308310
&self.const_usize(offset.bytes()),
309311
1,

compiler/rustc_codegen_llvm/src/debuginfo/gdb.rs

+3-4
Original file line numberDiff line numberDiff line change
@@ -15,12 +15,11 @@ use rustc_span::symbol::sym;
1515
/// .debug_gdb_scripts global is referenced, so it isn't removed by the linker.
1616
pub fn insert_reference_to_gdb_debug_scripts_section_global(bx: &mut Builder<'_, '_, '_>) {
1717
if needs_gdb_debug_scripts_section(bx) {
18-
let gdb_debug_scripts_section = get_or_insert_gdb_debug_scripts_section_global(bx);
18+
let gdb_debug_scripts_section =
19+
bx.const_bitcast(get_or_insert_gdb_debug_scripts_section_global(bx), bx.type_i8p());
1920
// Load just the first byte as that's all that's necessary to force
2021
// LLVM to keep around the reference to the global.
21-
let indices = [bx.const_i32(0), bx.const_i32(0)];
22-
let element = bx.inbounds_gep(gdb_debug_scripts_section, &indices);
23-
let volative_load_instruction = bx.volatile_load(bx.type_i8(), element);
22+
let volative_load_instruction = bx.volatile_load(bx.type_i8(), gdb_debug_scripts_section);
2423
unsafe {
2524
llvm::LLVMSetAlignment(volative_load_instruction, 1);
2625
}

compiler/rustc_codegen_llvm/src/intrinsic.rs

+12-4
Original file line numberDiff line numberDiff line change
@@ -686,11 +686,19 @@ fn codegen_emcc_try(
686686
// create an alloca and pass a pointer to that.
687687
let ptr_align = bx.tcx().data_layout.pointer_align.abi;
688688
let i8_align = bx.tcx().data_layout.i8_align.abi;
689-
let catch_data =
690-
catch.alloca(bx.type_struct(&[bx.type_i8p(), bx.type_bool()], false), ptr_align);
691-
let catch_data_0 = catch.inbounds_gep(catch_data, &[bx.const_usize(0), bx.const_usize(0)]);
689+
let catch_data_type = bx.type_struct(&[bx.type_i8p(), bx.type_bool()], false);
690+
let catch_data = catch.alloca(catch_data_type, ptr_align);
691+
let catch_data_0 = catch.inbounds_gep(
692+
catch_data_type,
693+
catch_data,
694+
&[bx.const_usize(0), bx.const_usize(0)],
695+
);
692696
catch.store(ptr, catch_data_0, ptr_align);
693-
let catch_data_1 = catch.inbounds_gep(catch_data, &[bx.const_usize(0), bx.const_usize(1)]);
697+
let catch_data_1 = catch.inbounds_gep(
698+
catch_data_type,
699+
catch_data,
700+
&[bx.const_usize(0), bx.const_usize(1)],
701+
);
694702
catch.store(is_rust_panic, catch_data_1, i8_align);
695703
let catch_data = catch.bitcast(catch_data, bx.type_i8p());
696704

compiler/rustc_codegen_llvm/src/llvm/ffi.rs

+8-4
Original file line numberDiff line numberDiff line change
@@ -1011,7 +1011,8 @@ extern "C" {
10111011
pub fn LLVMConstVector(ScalarConstantVals: *const &Value, Size: c_uint) -> &Value;
10121012

10131013
// Constant expressions
1014-
pub fn LLVMConstInBoundsGEP(
1014+
pub fn LLVMRustConstInBoundsGEP2(
1015+
ty: &'a Type,
10151016
ConstantVal: &'a Value,
10161017
ConstantIndices: *const &'a Value,
10171018
NumIndices: c_uint,
@@ -1394,22 +1395,25 @@ extern "C" {
13941395

13951396
pub fn LLVMBuildStore(B: &Builder<'a>, Val: &'a Value, Ptr: &'a Value) -> &'a Value;
13961397

1397-
pub fn LLVMBuildGEP(
1398+
pub fn LLVMBuildGEP2(
13981399
B: &Builder<'a>,
1400+
Ty: &'a Type,
13991401
Pointer: &'a Value,
14001402
Indices: *const &'a Value,
14011403
NumIndices: c_uint,
14021404
Name: *const c_char,
14031405
) -> &'a Value;
1404-
pub fn LLVMBuildInBoundsGEP(
1406+
pub fn LLVMBuildInBoundsGEP2(
14051407
B: &Builder<'a>,
1408+
Ty: &'a Type,
14061409
Pointer: &'a Value,
14071410
Indices: *const &'a Value,
14081411
NumIndices: c_uint,
14091412
Name: *const c_char,
14101413
) -> &'a Value;
1411-
pub fn LLVMBuildStructGEP(
1414+
pub fn LLVMBuildStructGEP2(
14121415
B: &Builder<'a>,
1416+
Ty: &'a Type,
14131417
Pointer: &'a Value,
14141418
Idx: c_uint,
14151419
Name: *const c_char,

compiler/rustc_codegen_llvm/src/va_arg.rs

+8-7
Original file line numberDiff line numberDiff line change
@@ -50,12 +50,12 @@ fn emit_direct_ptr_va_arg(
5050

5151
let aligned_size = size.align_to(slot_size).bytes() as i32;
5252
let full_direct_size = bx.cx().const_i32(aligned_size);
53-
let next = bx.inbounds_gep(addr, &[full_direct_size]);
53+
let next = bx.inbounds_gep(bx.type_i8(), addr, &[full_direct_size]);
5454
bx.store(next, va_list_addr, bx.tcx().data_layout.pointer_align.abi);
5555

5656
if size.bytes() < slot_size.bytes() && bx.tcx().sess.target.endian == Endian::Big {
5757
let adjusted_size = bx.cx().const_i32((slot_size.bytes() - size.bytes()) as i32);
58-
let adjusted = bx.inbounds_gep(addr, &[adjusted_size]);
58+
let adjusted = bx.inbounds_gep(bx.type_i8(), addr, &[adjusted_size]);
5959
(bx.bitcast(adjusted, bx.cx().type_ptr_to(llty)), addr_align)
6060
} else {
6161
(bx.bitcast(addr, bx.cx().type_ptr_to(llty)), addr_align)
@@ -98,6 +98,7 @@ fn emit_aapcs_va_arg(
9898
// Implementation of the AAPCS64 calling convention for va_args see
9999
// https://github.com/ARM-software/abi-aa/blob/master/aapcs64/aapcs64.rst
100100
let va_list_addr = list.immediate();
101+
let va_list_ty = list.deref(bx.cx).layout.llvm_type(bx);
101102
let layout = bx.cx.layout_of(target_ty);
102103

103104
let mut maybe_reg = bx.build_sibling_block("va_arg.maybe_reg");
@@ -109,11 +110,11 @@ fn emit_aapcs_va_arg(
109110

110111
let gr_type = target_ty.is_any_ptr() || target_ty.is_integral();
111112
let (reg_off, reg_top_index, slot_size) = if gr_type {
112-
let gr_offs = bx.struct_gep(va_list_addr, 7);
113+
let gr_offs = bx.struct_gep(va_list_ty, va_list_addr, 7);
113114
let nreg = (layout.size.bytes() + 7) / 8;
114115
(gr_offs, 3, nreg * 8)
115116
} else {
116-
let vr_off = bx.struct_gep(va_list_addr, 9);
117+
let vr_off = bx.struct_gep(va_list_ty, va_list_addr, 9);
117118
let nreg = (layout.size.bytes() + 15) / 16;
118119
(vr_off, 5, nreg * 16)
119120
};
@@ -141,15 +142,15 @@ fn emit_aapcs_va_arg(
141142
maybe_reg.cond_br(use_stack, &on_stack.llbb(), &in_reg.llbb());
142143

143144
let top_type = bx.type_i8p();
144-
let top = in_reg.struct_gep(va_list_addr, reg_top_index);
145+
let top = in_reg.struct_gep(va_list_ty, va_list_addr, reg_top_index);
145146
let top = in_reg.load(top_type, top, bx.tcx().data_layout.pointer_align.abi);
146147

147148
// reg_value = *(@top + reg_off_v);
148-
let mut reg_addr = in_reg.gep(top, &[reg_off_v]);
149+
let mut reg_addr = in_reg.gep(bx.type_i8(), top, &[reg_off_v]);
149150
if bx.tcx().sess.target.endian == Endian::Big && layout.size.bytes() != slot_size {
150151
// On big-endian systems the value is right-aligned in its slot.
151152
let offset = bx.const_i32((slot_size - layout.size.bytes()) as i32);
152-
reg_addr = in_reg.gep(reg_addr, &[offset]);
153+
reg_addr = in_reg.gep(bx.type_i8(), reg_addr, &[offset]);
153154
}
154155
let reg_type = layout.llvm_type(bx);
155156
let reg_addr = in_reg.bitcast(reg_addr, bx.cx.type_ptr_to(reg_type));

compiler/rustc_codegen_ssa/src/base.rs

+5-2
Original file line numberDiff line numberDiff line change
@@ -168,8 +168,11 @@ pub fn unsized_info<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>>(
168168
let ptr_ty = cx.type_i8p();
169169
let ptr_align = cx.tcx().data_layout.pointer_align.abi;
170170
let llvtable = bx.pointercast(old_info, bx.type_ptr_to(ptr_ty));
171-
let gep =
172-
bx.inbounds_gep(llvtable, &[bx.const_usize(u64::try_from(entry_idx).unwrap())]);
171+
let gep = bx.inbounds_gep(
172+
ptr_ty,
173+
llvtable,
174+
&[bx.const_usize(u64::try_from(entry_idx).unwrap())],
175+
);
173176
let new_vptr = bx.load(ptr_ty, gep, ptr_align);
174177
bx.nonnull_metadata(new_vptr);
175178
// Vtable loads are invariant.

compiler/rustc_codegen_ssa/src/meth.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ impl<'a, 'tcx> VirtualIndex {
2323
let llty = bx.fn_ptr_backend_type(fn_abi);
2424
let llvtable = bx.pointercast(llvtable, bx.type_ptr_to(llty));
2525
let ptr_align = bx.tcx().data_layout.pointer_align.abi;
26-
let gep = bx.inbounds_gep(llvtable, &[bx.const_usize(self.0)]);
26+
let gep = bx.inbounds_gep(llty, llvtable, &[bx.const_usize(self.0)]);
2727
let ptr = bx.load(llty, gep, ptr_align);
2828
bx.nonnull_metadata(ptr);
2929
// Vtable loads are invariant.
@@ -42,7 +42,7 @@ impl<'a, 'tcx> VirtualIndex {
4242
let llty = bx.type_isize();
4343
let llvtable = bx.pointercast(llvtable, bx.type_ptr_to(llty));
4444
let usize_align = bx.tcx().data_layout.pointer_align.abi;
45-
let gep = bx.inbounds_gep(llvtable, &[bx.const_usize(self.0)]);
45+
let gep = bx.inbounds_gep(llty, llvtable, &[bx.const_usize(self.0)]);
4646
let ptr = bx.load(llty, gep, usize_align);
4747
// Vtable loads are invariant.
4848
bx.set_invariant_load(ptr);

compiler/rustc_codegen_ssa/src/mir/intrinsic.rs

+6-2
Original file line numberDiff line numberDiff line change
@@ -116,14 +116,18 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
116116
OperandRef::from_const(bx, value, ret_ty).immediate_or_packed_pair(bx)
117117
}
118118
sym::offset => {
119+
let ty = substs.type_at(0);
120+
let layout = bx.layout_of(ty);
119121
let ptr = args[0].immediate();
120122
let offset = args[1].immediate();
121-
bx.inbounds_gep(ptr, &[offset])
123+
bx.inbounds_gep(bx.backend_type(layout), ptr, &[offset])
122124
}
123125
sym::arith_offset => {
126+
let ty = substs.type_at(0);
127+
let layout = bx.layout_of(ty);
124128
let ptr = args[0].immediate();
125129
let offset = args[1].immediate();
126-
bx.gep(ptr, &[offset])
130+
bx.gep(bx.backend_type(layout), ptr, &[offset])
127131
}
128132
sym::copy => {
129133
copy_intrinsic(

compiler/rustc_codegen_ssa/src/mir/operand.rs

+3-2
Original file line numberDiff line numberDiff line change
@@ -311,14 +311,15 @@ impl<'a, 'tcx, V: CodegenObject> OperandValue<V> {
311311
Abi::ScalarPair(ref a, ref b) => (a, b),
312312
_ => bug!("store_with_flags: invalid ScalarPair layout: {:#?}", dest.layout),
313313
};
314+
let ty = bx.backend_type(dest.layout);
314315
let b_offset = a_scalar.value.size(bx).align_to(b_scalar.value.align(bx).abi);
315316

316-
let llptr = bx.struct_gep(dest.llval, 0);
317+
let llptr = bx.struct_gep(ty, dest.llval, 0);
317318
let val = bx.from_immediate(a);
318319
let align = dest.align;
319320
bx.store_with_flags(val, llptr, align, flags);
320321

321-
let llptr = bx.struct_gep(dest.llval, 1);
322+
let llptr = bx.struct_gep(ty, dest.llval, 1);
322323
let val = bx.from_immediate(b);
323324
let align = dest.align.restrict_for_offset(b_offset);
324325
bx.store_with_flags(val, llptr, align, flags);

compiler/rustc_codegen_ssa/src/mir/place.rs

+13-5
Original file line numberDiff line numberDiff line change
@@ -103,12 +103,13 @@ impl<'a, 'tcx, V: CodegenObject> PlaceRef<'tcx, V> {
103103
if offset == a.value.size(bx.cx()).align_to(b.value.align(bx.cx()).abi) =>
104104
{
105105
// Offset matches second field.
106-
bx.struct_gep(self.llval, 1)
106+
let ty = bx.backend_type(self.layout);
107+
bx.struct_gep(ty, self.llval, 1)
107108
}
108109
Abi::Scalar(_) | Abi::ScalarPair(..) | Abi::Vector { .. } if field.is_zst() => {
109110
// ZST fields are not included in Scalar, ScalarPair, and Vector layouts, so manually offset the pointer.
110111
let byte_ptr = bx.pointercast(self.llval, bx.cx().type_i8p());
111-
bx.gep(byte_ptr, &[bx.const_usize(offset.bytes())])
112+
bx.gep(bx.cx().type_i8(), byte_ptr, &[bx.const_usize(offset.bytes())])
112113
}
113114
Abi::Scalar(_) | Abi::ScalarPair(..) => {
114115
// All fields of Scalar and ScalarPair layouts must have been handled by this point.
@@ -119,7 +120,10 @@ impl<'a, 'tcx, V: CodegenObject> PlaceRef<'tcx, V> {
119120
self.layout
120121
);
121122
}
122-
_ => bx.struct_gep(self.llval, bx.cx().backend_field_index(self.layout, ix)),
123+
_ => {
124+
let ty = bx.backend_type(self.layout);
125+
bx.struct_gep(ty, self.llval, bx.cx().backend_field_index(self.layout, ix))
126+
}
123127
};
124128
PlaceRef {
125129
// HACK(eddyb): have to bitcast pointers until LLVM removes pointee types.
@@ -185,7 +189,7 @@ impl<'a, 'tcx, V: CodegenObject> PlaceRef<'tcx, V> {
185189

186190
// Cast and adjust pointer.
187191
let byte_ptr = bx.pointercast(self.llval, bx.cx().type_i8p());
188-
let byte_ptr = bx.gep(byte_ptr, &[offset]);
192+
let byte_ptr = bx.gep(bx.cx().type_i8(), byte_ptr, &[offset]);
189193

190194
// Finally, cast back to the type expected.
191195
let ll_fty = bx.cx().backend_type(field);
@@ -380,7 +384,11 @@ impl<'a, 'tcx, V: CodegenObject> PlaceRef<'tcx, V> {
380384
};
381385

382386
PlaceRef {
383-
llval: bx.inbounds_gep(self.llval, &[bx.cx().const_usize(0), llindex]),
387+
llval: bx.inbounds_gep(
388+
bx.cx().backend_type(self.layout),
389+
self.llval,
390+
&[bx.cx().const_usize(0), llindex],
391+
),
384392
llextra: None,
385393
layout,
386394
align: self.align.restrict_for_offset(offset),

compiler/rustc_codegen_ssa/src/mir/rvalue.rs

+8-1
Original file line numberDiff line numberDiff line change
@@ -636,7 +636,14 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
636636
mir::BinOp::BitOr => bx.or(lhs, rhs),
637637
mir::BinOp::BitAnd => bx.and(lhs, rhs),
638638
mir::BinOp::BitXor => bx.xor(lhs, rhs),
639-
mir::BinOp::Offset => bx.inbounds_gep(lhs, &[rhs]),
639+
mir::BinOp::Offset => {
640+
let pointee_type = input_ty
641+
.builtin_deref(true)
642+
.unwrap_or_else(|| bug!("deref of non-pointer {:?}", input_ty))
643+
.ty;
644+
let llty = bx.cx().backend_type(bx.cx().layout_of(pointee_type));
645+
bx.inbounds_gep(llty, lhs, &[rhs])
646+
}
640647
mir::BinOp::Shl => common::build_unchecked_lshift(bx, lhs, rhs),
641648
mir::BinOp::Shr => common::build_unchecked_rshift(bx, input_ty, lhs, rhs),
642649
mir::BinOp::Ne

compiler/rustc_codegen_ssa/src/traits/builder.rs

+8-3
Original file line numberDiff line numberDiff line change
@@ -176,9 +176,14 @@ pub trait BuilderMethods<'a, 'tcx>:
176176
size: Size,
177177
);
178178

179-
fn gep(&mut self, ptr: Self::Value, indices: &[Self::Value]) -> Self::Value;
180-
fn inbounds_gep(&mut self, ptr: Self::Value, indices: &[Self::Value]) -> Self::Value;
181-
fn struct_gep(&mut self, ptr: Self::Value, idx: u64) -> Self::Value;
179+
fn gep(&mut self, ty: Self::Type, ptr: Self::Value, indices: &[Self::Value]) -> Self::Value;
180+
fn inbounds_gep(
181+
&mut self,
182+
ty: Self::Type,
183+
ptr: Self::Value,
184+
indices: &[Self::Value],
185+
) -> Self::Value;
186+
fn struct_gep(&mut self, ty: Self::Type, ptr: Self::Value, idx: u64) -> Self::Value;
182187

183188
fn trunc(&mut self, val: Self::Value, dest_ty: Self::Type) -> Self::Value;
184189
fn sext(&mut self, val: Self::Value, dest_ty: Self::Type) -> Self::Value;

compiler/rustc_llvm/llvm-wrapper/RustWrapper.cpp

+10
Original file line numberDiff line numberDiff line change
@@ -1551,6 +1551,16 @@ extern "C" void LLVMRustSetLinkage(LLVMValueRef V,
15511551
LLVMSetLinkage(V, fromRust(RustLinkage));
15521552
}
15531553

1554+
extern "C" LLVMValueRef LLVMRustConstInBoundsGEP2(LLVMTypeRef Ty,
1555+
LLVMValueRef ConstantVal,
1556+
LLVMValueRef *ConstantIndices,
1557+
unsigned NumIndices) {
1558+
ArrayRef<Constant *> IdxList(unwrap<Constant>(ConstantIndices, NumIndices),
1559+
NumIndices);
1560+
Constant *Val = unwrap<Constant>(ConstantVal);
1561+
return wrap(ConstantExpr::getInBoundsGetElementPtr(unwrap(Ty), Val, IdxList));
1562+
}
1563+
15541564
// Returns true if both high and low were successfully set. Fails in case constant wasn’t any of
15551565
// the common sizes (1, 8, 16, 32, 64, 128 bits)
15561566
extern "C" bool LLVMRustConstInt128Get(LLVMValueRef CV, bool sext, uint64_t *high, uint64_t *low)

0 commit comments

Comments
 (0)