1; RUN: llc < %s -march=avr -filetype=asm | FileCheck %s -check-prefix=CHECK-ASM 2; RUN: llc < %s -march=avr -filetype=obj | llvm-objdump -Dr - \ 3; RUN: | FileCheck %s -check-prefix=CHECK-OBJ 4 5; Somewhat pruned test case from rustc using trait objects 6 7%TraitObjectA = type {} 8 9; CHECK-ASM-LABEL: vtable.0: 10; CHECK-ASM-NEXT: .short pm(drop_in_place2) 11; CHECK-ASM-NEXT: .short 0 12; CHECK-ASM-NEXT: .short 1 13; CHECK-ASM-NEXT: .short pm(trait_fn2) 14 15; CHECK-OBJ-LABEL: <vtable.0>: 16; CHECK-OBJ-NEXT: 00 00 17; CHECK-OBJ-NEXT: R_AVR_16_PM .text 18; CHECK-OBJ-NEXT: 00 00 19; CHECK-OBJ-NEXT: 01 00 00 00 20; CHECK-OBJ-NEXT: R_AVR_16_PM .text 21@vtable.0 = private constant { 22 void (%TraitObjectA*) addrspace(1)*, 23 i16, 24 i16, 25 i8 (%TraitObjectA*) addrspace(1)* 26 } { 27 void (%TraitObjectA*) addrspace(1)* 28 @drop_in_place2, 29 i16 0, 30 i16 1, 31 i8 (%TraitObjectA*) addrspace(1)* 32 @trait_fn2 33 }, align 1 34 35; CHECK-ASM-LABEL: vtable.1: 36; CHECK-ASM-NEXT: .short pm(drop_in_place1) 37; CHECK-ASM-NEXT: .short 0 38; CHECK-ASM-NEXT: .short 1 39; CHECK-ASM-NEXT: .short pm(trait_fn1) 40 41; CHECK-OBJ-LABEL: <vtable.1>: 42; CHECK-OBJ-NEXT: 00 00 43; CHECK-OBJ-NEXT: R_AVR_16_PM .text 44; CHECK-OBJ-NEXT: 00 00 45; CHECK-OBJ-NEXT: 01 00 00 00 46; CHECK-OBJ-NEXT: R_AVR_16_PM .text 47@vtable.1 = private constant { 48 void (%TraitObjectA*) addrspace(1)*, 49 i16, 50 i16, 51 i8 (%TraitObjectA*) addrspace(1)* 52 } { 53 void (%TraitObjectA*) addrspace(1)* 54 @drop_in_place1, 55 i16 0, 56 i16 1, 57 i8 (%TraitObjectA*) addrspace(1)* 58 @trait_fn1 59 }, align 1 60 61define internal fastcc i8 @TraitObjectA_method(i1 zeroext %choice) addrspace(1) { 62start: 63 %b = alloca %TraitObjectA, align 1 64 65 %c = select i1 %choice, [3 x i16]* bitcast ({ 66 void (%TraitObjectA*) addrspace(1)*, 67 i16, 68 i16, 69 i8 (%TraitObjectA*) addrspace(1)* 70 }* @vtable.0 to [3 x i16]*), 71 [3 x i16]* bitcast ({ 72 void (%TraitObjectA*) addrspace(1)*, 73 i16, 74 i16, 75 i8 (%TraitObjectA*) addrspace(1)* 76 }* @vtable.1 to [3 x i16]*) 77 %b2 = bitcast %TraitObjectA* %b to {}* 78 79 %res = call fastcc addrspace(1) i8 @call_trait_object({}* nonnull align 1 %b2, [3 x i16]* noalias readonly align 1 dereferenceable(6) %c) 80 ret i8 %res 81} 82 83define internal fastcc i8 @call_trait_object({}* nonnull align 1 %a, [3 x i16]* noalias nocapture readonly align 1 dereferenceable(6) %b) addrspace(1) { 84start: 85 %b2 = getelementptr inbounds [3 x i16], [3 x i16]* %b, i16 0, i16 3 86 %c = bitcast i16* %b2 to i8 ({}*) addrspace(1)** 87 %d = load i8 ({}*) addrspace(1)*, i8 ({}*) addrspace(1)** %c, align 1, !invariant.load !1, !nonnull !1 88 %res = tail call addrspace(1) i8 %d({}* nonnull align 1 %a) 89 ret i8 %res 90} 91 92define internal void @drop_in_place1(%TraitObjectA* nocapture %a) addrspace(1) { 93start: 94 ret void 95} 96 97define internal i8 @trait_fn1(%TraitObjectA* noalias nocapture nonnull readonly align 1 %self) addrspace(1) { 98start: 99 ret i8 89 100} 101 102define internal void @drop_in_place2(%TraitObjectA* nocapture %a) addrspace(1) { 103start: 104 ret void 105} 106 107define internal i8 @trait_fn2(%TraitObjectA* noalias nocapture nonnull readonly align 1 %self) addrspace(1) { 108start: 109 ret i8 79 110} 111 112!1 = !{} 113