Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

CFI and FullLTO crashes in DAG Instruction Selection with Assertion in `isa<To>(Val) && "cast<Ty>() argument of incompatible type!"' failed. #112053

Closed
gulfemsavrun opened this issue Oct 11, 2024 · 4 comments · Fixed by #112787
Assignees
Labels
compiler-rt:cfi Control Flow Integrity ipo Interprocedural optimizations llvm:codegen LTO Link time optimization (regular/full LTO or ThinLTO)

Comments

@gulfemsavrun
Copy link
Contributor

When we combine Full LTO (aka traditional LTO) with CFI, we run into the following assertion failure:

FAILED: kernel_x64/obj/zircon/system/ulib/pretty/pretty.hexdump.cc.o 
../../prebuilt/third_party/python3/linux-x64/bin/python3 -S ../../build/tracer/restat_cacher.py --outputs {{output}} {{output}}.d --   ../clang-ci-linux-build-install/bin/clang++ -MD -MF kernel_x64/obj/zircon/system/ulib/pretty/pretty.hexdump.cc.o.d -o kernel_x64/obj/zircon/system/ulib/pretty/pretty.hexdump.cc.o -D_LIBCPP_DISABLE_VISIBILITY_ANNOTATIONS -D_LIBCPP_ENABLE_THREAD_SAFETY_ANNOTATIONS=1 -DKERNEL_BASE=0xffffffff80100000 -DSMP_MAX_CPUS=32 -D_KERNEL -DLK -DENABLE_PANIC_SHELL -DZIRCON_TOOLCHAIN -DLK_DEBUGLEVEL=2 -DDEBUG_PRINT_LEVEL=2 -DVM_TRACING_LEVEL=0 -DFUTEX_BLOCK_TRACING_ENABLED=false -DLOCK_TRACING_ENABLED=false -DEXPERIMENTAL_THREAD_SAMPLER_ENABLED=false -DJTRACE_TARGET_BUFFER_SIZE=0 -DSCHEDULER_TRACING_LEVEL=0 -DSCHEDULER_QUEUE_TRACING_ENABLED=false -DSCHEDULER_EXTRA_INVARIANT_VALIDATION=false -DSCHEDULER_LOCK_SPIN_TRACING_COMPRESSED=false -DSCHEDULER_LOCK_SPIN_TRACING_ENABLED=false -DWAIT_QUEUE_DEPTH_TRACING_ENABLED=false -DVIRTUAL_HEAP=0 -DHARDEN_SLS -DKERNEL_RETPOLINE=1 -DX64_KERNEL_JCC_WORKAROUND -DARCH_X86 -DKERNEL_LOAD_OFFSET=0x00100000 -DZERO_CALL_USED_REGS -DKERNEL_IMAGE_MAX_SIZE=67108864 -DWITH_FRAME_POINTERS=1 -DZX_ASSERT_LEVEL=2 -I../../zircon/kernel/include -I../../zircon/kernel/lib/libc/include -I../../zircon/kernel/lib/ktl/include -I../../sdk/lib/fit/include -I../../sdk/lib/stdcompat/include -I../../zircon/kernel/lib/heap/include -I../../zircon/kernel/lib/lockup_detector/include -I../../zircon/system/ulib/lazy_init/include -I../../zircon/system/ulib/lockdep/include -I../../zircon/system/ulib/ffl/include -I../../zircon/kernel/lib/kconcurrent/include -I../../zircon/system/ulib/concurrent/include -I../../zircon/kernel/vm/include -I../../zircon/kernel/vm/phys/include -I../../zircon/kernel/lib/user_copy/include -I../../zircon/kernel/lib/acpi_lite/include -I../../zircon/kernel/lib/boot-options/include -I../../zircon/kernel/lib/devicetree/include -I../../zircon/system/ulib/uart/include -I../../zircon/system/ulib/hwreg/include -I../../zircon/kernel/phys/lib/memalloc/include -I../../zircon/system/ulib/zircon-internal/include -I../../zircon/kernel/lib/ktrace/include -I../../zircon/kernel/lib/special-sections/include -I../../src/performance/lib/fxt/include -I../../zircon/system/ulib/fbl/include -I../../zircon/kernel/lib/fbl/include -I../../zircon/system/ulib/mmio-ptr/include -I../../zircon/system/ulib/zx/include -I../../zircon/kernel/lib/backtrace/include -I../../zircon/kernel/lib/version/include -I../../zircon/kernel/lib/wake-vector/include -I../../zircon/kernel/lib/arch/x86/include -I../../zircon/kernel/lib/arch/include -I../../sdk/lib/zbi-format/include -I../../zircon/system/public -I../../zircon/kernel/arch/x86/include -I../../zircon/system/ulib/bitmap/include -I../../zircon/kernel/arch/x86/page_tables/include -I../../zircon/system/ulib/page_tables/include -I../../zircon/system/ulib/pretty/include -idirafter ../../zircon/kernel/lib/libc/include-after -idirafter ../../zircon/kernel/lib/ktl/include-after -Xclang -debug-info-kind=constructor -g3 -grecord-gcc-switches -gdwarf-4 -gz=zstd -fdata-sections -ffunction-sections -O2 -flto -mllvm -wholeprogramdevirt-branch-funnel-threshold=0 -ffat-lto-objects -fwhole-program-vtables -fsanitize=cfi-cast-strict -fsanitize=cfi-derived-cast -fsanitize=cfi-unrelated-cast -fsanitize=cfi-nvcall -fsanitize=cfi-vcall -fsanitize=cfi-icall -fsanitize=cfi-mfcall -Wall -Wextra -Wconversion -Wextra-semi -Wimplicit-fallthrough -Wnewline-eof -Wstrict-prototypes -Wwrite-strings -Wno-sign-conversion -Wno-unused-parameter -Wnonportable-system-include-path -Wno-missing-field-initializers -Wno-extra-qualification -Wno-cast-function-type-strict -Wno-cast-function-type-mismatch -Wno-unknown-warning-option -Wno-missing-template-arg-list-after-template-kw -Wno-deprecated-pragma -ftrivial-auto-var-init=pattern -ffile-compilation-dir=. -no-canonical-prefixes -fvisibility=hidden -Wthread-safety -Wno-unknown-warning-option -Wno-thread-safety-reference-return -Werror -Wa,--fatal-warnings -Wno-error=deprecated-declarations -fno-common -fsized-deallocation --target=x86_64-fuchsia -march=x86-64-v2 -mtune=generic -mbranches-within-32B-boundaries -fcolor-diagnostics -fcrash-diagnostics-dir=clang-crashreports -fcrash-diagnostics=all -ffuchsia-api-level=4293918720 -fpie -ffreestanding -include ../../zircon/kernel/include/hidden.h -fno-unwind-tables -mno-red-zone -Wformat=2 -Wmissing-declarations -Wvla -Wshadow -mno-red-zone -mfsgsbase -msoft-float -mno-mmx -mno-sse -mno-sse2 -mno-3dnow -mno-avx -mno-avx2 -mcmodel=kernel -mharden-sls=all -mretpoline -mretpoline-external-thunk -mbranches-within-32B-boundaries -fno-finite-loops -fzero-call-used-regs=used-gpr -fdata-sections -fno-omit-frame-pointer -momit-leaf-frame-pointer -fno-omit-frame-pointer -momit-leaf-frame-pointer -fdata-sections -ffunction-sections -Wno-gnu-string-literal-operator-template -Wno-deprecated-this-capture -std=c++20 -fno-exceptions -fno-rtti -Xclang -fexperimental-omit-vtable-rtti -fvisibility-inlines-hidden -ftemplate-backtrace-limit=0 -faligned-new=8 -fno-exceptions -c ../../zircon/system/ulib/pretty/hexdump.cc
clang++: llvm/include/llvm/Support/Casting.h:578: decltype(auto) llvm::cast(From *) [To = llvm::MDNode, From = llvm::Metadata]: Assertion `isa<To>(Val) && "cast<Ty>() argument of incompatible type!"' failed.
PLEASE submit a bug report to https://github.com/llvm/llvm-project/issues/ and include the crash backtrace, preprocessed source, and associated run script.
Stack dump:
0.	Program arguments: ../clang-ci-linux-build-install/bin/clang++ -MD -MF kernel_x64/obj/zircon/system/ulib/pretty/pretty.hexdump.cc.o.d -o kernel_x64/obj/zircon/system/ulib/pretty/pretty.hexdump.cc.o -D_LIBCPP_DISABLE_VISIBILITY_ANNOTATIONS -D_LIBCPP_ENABLE_THREAD_SAFETY_ANNOTATIONS=1 -DKERNEL_BASE=0xffffffff80100000 -DSMP_MAX_CPUS=32 -D_KERNEL -DLK -DENABLE_PANIC_SHELL -DZIRCON_TOOLCHAIN -DLK_DEBUGLEVEL=2 -DDEBUG_PRINT_LEVEL=2 -DVM_TRACING_LEVEL=0 -DFUTEX_BLOCK_TRACING_ENABLED=false -DLOCK_TRACING_ENABLED=false -DEXPERIMENTAL_THREAD_SAMPLER_ENABLED=false -DJTRACE_TARGET_BUFFER_SIZE=0 -DSCHEDULER_TRACING_LEVEL=0 -DSCHEDULER_QUEUE_TRACING_ENABLED=false -DSCHEDULER_EXTRA_INVARIANT_VALIDATION=false -DSCHEDULER_LOCK_SPIN_TRACING_COMPRESSED=false -DSCHEDULER_LOCK_SPIN_TRACING_ENABLED=false -DWAIT_QUEUE_DEPTH_TRACING_ENABLED=false -DVIRTUAL_HEAP=0 -DHARDEN_SLS -DKERNEL_RETPOLINE=1 -DX64_KERNEL_JCC_WORKAROUND -DARCH_X86 -DKERNEL_LOAD_OFFSET=0x00100000 -DZERO_CALL_USED_REGS -DKERNEL_IMAGE_MAX_SIZE=67108864 -DWITH_FRAME_POINTERS=1 -DZX_ASSERT_LEVEL=2 -I../../zircon/kernel/include -I../../zircon/kernel/lib/libc/include -I../../zircon/kernel/lib/ktl/include -I../../sdk/lib/fit/include -I../../sdk/lib/stdcompat/include -I../../zircon/kernel/lib/heap/include -I../../zircon/kernel/lib/lockup_detector/include -I../../zircon/system/ulib/lazy_init/include -I../../zircon/system/ulib/lockdep/include -I../../zircon/system/ulib/ffl/include -I../../zircon/kernel/lib/kconcurrent/include -I../../zircon/system/ulib/concurrent/include -I../../zircon/kernel/vm/include -I../../zircon/kernel/vm/phys/include -I../../zircon/kernel/lib/user_copy/include -I../../zircon/kernel/lib/acpi_lite/include -I../../zircon/kernel/lib/boot-options/include -I../../zircon/kernel/lib/devicetree/include -I../../zircon/system/ulib/uart/include -I../../zircon/system/ulib/hwreg/include -I../../zircon/kernel/phys/lib/memalloc/include -I../../zircon/system/ulib/zircon-internal/include -I../../zircon/kernel/lib/ktrace/include -I../../zircon/kernel/lib/special-sections/include -I../../src/performance/lib/fxt/include -I../../zircon/system/ulib/fbl/include -I../../zircon/kernel/lib/fbl/include -I../../zircon/system/ulib/mmio-ptr/include -I../../zircon/system/ulib/zx/include -I../../zircon/kernel/lib/backtrace/include -I../../zircon/kernel/lib/version/include -I../../zircon/kernel/lib/wake-vector/include -I../../zircon/kernel/lib/arch/x86/include -I../../zircon/kernel/lib/arch/include -I../../sdk/lib/zbi-format/include -I../../zircon/system/public -I../../zircon/kernel/arch/x86/include -I../../zircon/system/ulib/bitmap/include -I../../zircon/kernel/arch/x86/page_tables/include -I../../zircon/system/ulib/page_tables/include -I../../zircon/system/ulib/pretty/include -idirafter ../../zircon/kernel/lib/libc/include-after -idirafter ../../zircon/kernel/lib/ktl/include-after -Xclang -debug-info-kind=constructor -g3 -grecord-gcc-switches -gdwarf-4 -gz=zstd -fdata-sections -ffunction-sections -O2 -flto -mllvm -wholeprogramdevirt-branch-funnel-threshold=0 -ffat-lto-objects -fwhole-program-vtables -fsanitize=cfi-cast-strict -fsanitize=cfi-derived-cast -fsanitize=cfi-unrelated-cast -fsanitize=cfi-nvcall -fsanitize=cfi-vcall -fsanitize=cfi-icall -fsanitize=cfi-mfcall -Wall -Wextra -Wconversion -Wextra-semi -Wimplicit-fallthrough -Wnewline-eof -Wstrict-prototypes -Wwrite-strings -Wno-sign-conversion -Wno-unused-parameter -Wnonportable-system-include-path -Wno-missing-field-initializers -Wno-extra-qualification -Wno-cast-function-type-strict -Wno-cast-function-type-mismatch -Wno-unknown-warning-option -Wno-missing-template-arg-list-after-template-kw -Wno-deprecated-pragma -ftrivial-auto-var-init=pattern -ffile-compilation-dir=. -no-canonical-prefixes -fvisibility=hidden -Wthread-safety -Wno-unknown-warning-option -Wno-thread-safety-reference-return -Werror -Wa,--fatal-warnings -Wno-error=deprecated-declarations -fno-common -fsized-deallocation --target=x86_64-fuchsia -march=x86-64-v2 -mtune=generic -mbranches-within-32B-boundaries -fcolor-diagnostics -fcrash-diagnostics-dir=clang-crashreports -fcrash-diagnostics=all -ffuchsia-api-level=4293918720 -fpie -ffreestanding -include ../../zircon/kernel/include/hidden.h -fno-unwind-tables -mno-red-zone -Wformat=2 -Wmissing-declarations -Wvla -Wshadow -mno-red-zone -mfsgsbase -msoft-float -mno-mmx -mno-sse -mno-sse2 -mno-3dnow -mno-avx -mno-avx2 -mcmodel=kernel -mharden-sls=all -mretpoline -mretpoline-external-thunk -mbranches-within-32B-boundaries -fno-finite-loops -fzero-call-used-regs=used-gpr -fdata-sections -fno-omit-frame-pointer -momit-leaf-frame-pointer -fno-omit-frame-pointer -momit-leaf-frame-pointer -fdata-sections -ffunction-sections -Wno-gnu-string-literal-operator-template -Wno-deprecated-this-capture -std=c++20 -fno-exceptions -fno-rtti -Xclang -fexperimental-omit-vtable-rtti -fvisibility-inlines-hidden -ftemplate-backtrace-limit=0 -faligned-new=8 -fno-exceptions -c ../../zircon/system/ulib/pretty/hexdump.cc
1.	<eof> parser at end of file
2.	Code generation
3.	Running pass 'Function Pass Manager' on module '../../zircon/system/ulib/pretty/hexdump.cc'.
4.	Running pass 'X86 DAG->DAG Instruction Selection' on function '@hexdump_very_ex'
#0 0x0000558bcfc66028 (../clang-ci-linux-build-install/bin/clang+++0x91d0028)
clang++: error: clang frontend command failed with exit code 134 (use -v to see invocation)
@EugeneZelenko EugeneZelenko added compiler-rt:cfi Control Flow Integrity LTO Link time optimization (regular/full LTO or ThinLTO) and removed new issue labels Oct 11, 2024
@gulfemsavrun
Copy link
Contributor Author

I'm attaching the crash reproducer.
clang-crashreports.zip

@gulfemsavrun gulfemsavrun changed the title CFI and FullLTO results in Assertion `isa<To>(Val) && "cast<Ty>() argument of incompatible type!"' failed. CFI and FullLTO crashes in DAG Instruction Selection with Assertion in `isa<To>(Val) && "cast<Ty>() argument of incompatible type!"' failed. Oct 11, 2024
@gulfemsavrun gulfemsavrun added the llvm:SelectionDAG SelectionDAGISel as well label Oct 11, 2024
@ilovepi ilovepi self-assigned this Oct 12, 2024
@ilovepi
Copy link
Contributor

ilovepi commented Oct 12, 2024

I'll look into this next week. I believe this is related to CFI's interaction with FatLTO.

@ilovepi
Copy link
Contributor

ilovepi commented Oct 16, 2024

I was able to get some reduced IR.

target datalayout = "e-m:e-p270:32:32-p271:32:32-p272:64:64-i64:64-i128:128-f80:128-n8:16:32:64-S128"
target triple = "x86_64-unknown-fuchsia"

define void @hexdump_very_ex() {
entry:
  %0 = tail call i1 @llvm.type.test(ptr null, metadata !"_ZTSFvPvPKczE")
  ret void
}

; Function Attrs: nocallback nofree nosync nounwind speculatable willreturn memory(none)
declare i1 @llvm.type.test(ptr, metadata) #0

attributes #0 = { nocallback nofree nosync nounwind speculatable willreturn memory(none) }

@ilovepi
Copy link
Contributor

ilovepi commented Oct 16, 2024

That's from a much larger function though.

; Function Attrs: noimplicitfloat noredzone nounwind safestack sspstrong
define hidden void @hexdump_very_ex(ptr noundef %ptr, i64 noundef %len, i64 noundef %disp_addr, ptr noundef %printf_func, ptr noundef %printf_arg) local_unnamed_addr #0 !dbg !1158 !type !1195 !type !1196 {
entry:
  %u = alloca %union.anon, align 4
    #dbg_value(ptr %ptr, !1165, !DIExpression(), !1197)
    #dbg_value(i64 %len, !1166, !DIExpression(), !1197)
    #dbg_value(i64 %disp_addr, !1167, !DIExpression(), !1197)
    #dbg_value(ptr %printf_func, !1168, !DIExpression(), !1197)
    #dbg_value(ptr %printf_arg, !1169, !DIExpression(), !1197)
    #dbg_value(ptr %ptr, !1170, !DIExpression(), !1197)
    #dbg_value(i64 -6148914691236517206, !1171, !DIExpression(), !1197)
    #dbg_value(i64 0, !1171, !DIExpression(), !1197)
  %cmp79.not = icmp eq i64 %len, 0, !dbg !1198
  br i1 %cmp79.not, label %for.end38, label %for.body.lr.ph, !dbg !1199

for.body.lr.ph:                                   ; preds = %entry
  %0 = ptrtoint ptr %ptr to i64, !dbg !1200
    #dbg_value(i64 %0, !1170, !DIExpression(), !1197)
  %1 = tail call i1 @llvm.type.test(ptr %printf_func, metadata !"_ZTSFvPvPKczE"), !nosanitize !46
  %add4 = add i64 %disp_addr, %len
  %cmp5 = icmp ugt i64 %add4, 4294967295
  %cond6 = select i1 %cmp5, ptr @.str, ptr @.str.1
  br label %for.body, !dbg !1199

for.body:                                         ; preds = %for.body.lr.ph, %cont34
  %indvars.iv = phi i64 [ %len, %for.body.lr.ph ], [ %indvars.iv.next, %cont34 ]
  %address.081 = phi i64 [ %0, %for.body.lr.ph ], [ %add35, %cont34 ]
  %count.080 = phi i64 [ 0, %for.body.lr.ph ], [ %add37, %cont34 ]
  %umin87 = call i64 @llvm.umin.i64(i64 %indvars.iv, i64 16), !dbg !1201
  %2 = add nuw nsw i64 %umin87, 3, !dbg !1201
  %3 = lshr i64 %2, 2, !dbg !1201
  %umax88 = call i64 @llvm.umax.i64(i64 %3, i64 1), !dbg !1201
  %4 = sub i64 4, %umax88, !dbg !1201
  %umin84 = call i64 @llvm.umin.i64(i64 %indvars.iv, i64 16), !dbg !1201
  %5 = add nuw nsw i64 %umin84, 3, !dbg !1201
  %6 = lshr i64 %5, 2, !dbg !1201
  %umax85 = call i64 @llvm.umax.i64(i64 %6, i64 1), !dbg !1201
    #dbg_value(i64 %address.081, !1170, !DIExpression(), !1197)
    #dbg_value(i64 %count.080, !1171, !DIExpression(), !1197)
  call void @llvm.lifetime.start.p0(i64 16, ptr nonnull %u) #8, !dbg !1201
    #dbg_declare(ptr %u, !1172, !DIExpression(), !1202)
  store i32 -1431655766, ptr %u, align 4, !dbg !1202, !annotation !1146
  %sunkaddr = getelementptr inbounds i8, ptr %u, i64 4, !dbg !1202
  store i32 -1431655766, ptr %sunkaddr, align 4, !dbg !1202, !annotation !1146
  %sunkaddr90 = getelementptr inbounds i8, ptr %u, i64 8, !dbg !1202
  store i32 -1431655766, ptr %sunkaddr90, align 4, !dbg !1202, !annotation !1146
  %sunkaddr91 = getelementptr inbounds i8, ptr %u, i64 12, !dbg !1202
  store i32 -1431655766, ptr %sunkaddr91, align 4, !dbg !1202, !annotation !1146
  %sub = sub nuw i64 %len, %count.080, !dbg !1203
  %cond = tail call i64 @llvm.umin.i64(i64 %sub, i64 16), !dbg !1204
    #dbg_value(i64 %cond, !1185, !DIExpression(), !1205)
    #dbg_value(i32 4, !1188, !DIExpression(), !1205)
  %sub3 = add nuw nsw i64 %cond, 3, !dbg !1206
  %mul = and i64 %sub3, 60, !dbg !1207
    #dbg_value(i64 %mul, !1184, !DIExpression(), !1208)
    #dbg_value(i64 -6148914691236517206, !1190, !DIExpression(), !1208)
  br i1 %1, label %for.body11.lr.ph, label %trap, !dbg !1209, !nosanitize !46

trap:                                             ; preds = %for.body
  tail call void @llvm.ubsantrap(i8 2) #9, !dbg !1208, !nosanitize !46
  unreachable, !dbg !1209, !nosanitize !46

for.body11.lr.ph:                                 ; preds = %for.body
  %add7 = add i64 %count.080, %disp_addr, !dbg !1210
  tail call void (ptr, ptr, ...) %printf_func(ptr noundef %printf_arg, ptr noundef nonnull %cond6, i64 noundef %add7) #7, !dbg !1209
    #dbg_value(i64 0, !1190, !DIExpression(), !1208)
  br label %for.body11, !dbg !1211

for.cond15.preheader:                             ; preds = %for.body11
    #dbg_value(i64 poison, !1190, !DIExpression(), !1208)
  %cmp1675 = icmp ult i64 %indvars.iv, 13, !dbg !1213
  br i1 %cmp1675, label %cont18.preheader, label %cont22, !dbg !1216

cont18.preheader:                                 ; preds = %for.cond15.preheader
  br label %cont18, !dbg !1216

for.body11:                                       ; preds = %for.body11.lr.ph, %for.body11
  %i.074 = phi i64 [ 0, %for.body11.lr.ph ], [ %inc, %for.body11 ]
  %7 = inttoptr i64 %address.081 to ptr
    #dbg_value(i64 %i.074, !1190, !DIExpression(), !1208)
  %8 = shl nuw nsw i64 %i.074, 2, !dbg !1217
  %scevgep86 = getelementptr i8, ptr %7, i64 %8, !dbg !1217
  %9 = load i32, ptr %scevgep86, align 4, !dbg !1217, !tbaa !1220
  %10 = shl nuw nsw i64 %i.074, 2, !dbg !1224
  %scevgep = getelementptr i8, ptr %u, i64 %10, !dbg !1224
  store i32 %9, ptr %scevgep, align 4, !dbg !1224, !tbaa !1225
  tail call void (ptr, ptr, ...) %printf_func(ptr noundef %printf_arg, ptr noundef nonnull @.str.2, i32 noundef %9) #7, !dbg !1226
  %inc = add nuw nsw i64 %i.074, 1, !dbg !1227
    #dbg_value(i64 %inc, !1190, !DIExpression(), !1208)
  %exitcond.not = icmp eq i64 %umax85, %inc, !dbg !1228
  br i1 %exitcond.not, label %for.cond15.preheader, label %for.body11, !dbg !1211, !llvm.loop !1229

cont18:                                           ; preds = %cont18.preheader, %cont18
  %lsr.iv = phi i64 [ %4, %cont18.preheader ], [ %lsr.iv.next, %cont18 ]
    #dbg_value(i64 poison, !1190, !DIExpression(), !1208)
  tail call void (ptr, ptr, ...) %printf_func(ptr noundef %printf_arg, ptr noundef nonnull @.str.3) #7, !dbg !1231
    #dbg_value(i64 poison, !1190, !DIExpression(DW_OP_plus_uconst, 1, DW_OP_stack_value), !1208)
  %lsr.iv.next = add i64 %lsr.iv, -1, !dbg !1213
  %exitcond82.not = icmp eq i64 %lsr.iv.next, 0, !dbg !1213
  br i1 %exitcond82.not, label %cont22, label %cont18, !dbg !1216, !llvm.loop !1233

cont22:                                           ; preds = %cont18, %for.cond15.preheader
  tail call void (ptr, ptr, ...) %printf_func(ptr noundef %printf_arg, ptr noundef nonnull @.str.4) #7, !dbg !1235
    #dbg_value(i64 0, !1190, !DIExpression(), !1208)
  br label %for.body25, !dbg !1236

for.body25:                                       ; preds = %cont22, %if.end
  %i.277 = phi i64 [ 0, %cont22 ], [ %inc32, %if.end ]
    #dbg_value(i64 %i.277, !1190, !DIExpression(), !1208)
    #dbg_value(i8 poison, !1191, !DIExpression(), !1237)
  %cmp27 = icmp ult i64 %i.277, %mul, !dbg !1238
  br i1 %cmp27, label %land.lhs.true, label %cont30, !dbg !1240

land.lhs.true:                                    ; preds = %for.body25
  %scevgep89 = getelementptr i8, ptr %u, i64 %i.277, !dbg !1241
  %11 = load i8, ptr %scevgep89, align 1, !dbg !1241, !tbaa !1225
    #dbg_value(i8 %11, !1191, !DIExpression(), !1237)
  %conv = sext i8 %11 to i32, !dbg !1242
  %call = tail call i32 @isprint(i32 noundef %conv) #7, !dbg !1243
  %tobool.not = icmp eq i32 %call, 0, !dbg !1243
  br i1 %tobool.not, label %cont30, label %cont28, !dbg !1240

cont28:                                           ; preds = %land.lhs.true
  tail call void (ptr, ptr, ...) %printf_func(ptr noundef %printf_arg, ptr noundef nonnull @.str.5, i32 noundef %conv) #7, !dbg !1244
  br label %if.end, !dbg !1246

cont30:                                           ; preds = %for.body25, %land.lhs.true
  tail call void (ptr, ptr, ...) %printf_func(ptr noundef %printf_arg, ptr noundef nonnull @.str.6) #7, !dbg !1247
  br label %if.end

if.end:                                           ; preds = %cont30, %cont28
  %inc32 = add nuw nsw i64 %i.277, 1, !dbg !1249
    #dbg_value(i64 %inc32, !1190, !DIExpression(), !1208)
  %exitcond83.not = icmp eq i64 %inc32, 16, !dbg !1250
  br i1 %exitcond83.not, label %cont34, label %for.body25, !dbg !1236, !llvm.loop !1251

cont34:                                           ; preds = %if.end
  tail call void (ptr, ptr, ...) %printf_func(ptr noundef %printf_arg, ptr noundef nonnull @.str.7) #7, !dbg !1253
  %add35 = add i64 %address.081, 16, !dbg !1254
    #dbg_value(i64 %add35, !1170, !DIExpression(), !1197)
  call void @llvm.lifetime.end.p0(i64 16, ptr nonnull %u) #8, !dbg !1255
  %add37 = add i64 %count.080, 16, !dbg !1256
    #dbg_value(i64 %add37, !1171, !DIExpression(), !1197)
  %indvars.iv.next = add i64 %indvars.iv, -16, !dbg !1199
  %cmp = icmp ult i64 %add37, %len, !dbg !1198
  br i1 %cmp, label %for.body, label %for.end38, !dbg !1199, !llvm.loop !1257

for.end38:                                        ; preds = %cont34, %entry
  ret void, !dbg !1259
}

; Function Attrs: mustprogress nocallback nofree nosync nounwind speculatable willreturn memory(none)
declare i1 @llvm.type.test(ptr, metadata) #4

; Function Attrs: cold noreturn nounwind
declare void @llvm.ubsantrap(i8 immarg) #5

; Function Attrs: noimplicitfloat noredzone
declare !dbg !1260 !type !1264 !type !1265 hidden i32 @isprint(i32 noundef) local_unnamed_addr #3

; Function Attrs: noimplicitfloat noredzone nounwind safestack sspstrong
define hidden void @hexdump8_very_ex(ptr noundef %ptr, i64 noundef %len, i64 noundef %disp_addr, ptr noundef %printf_func, ptr noundef %printf_arg) local_unnamed_addr #0 !dbg !1266 !type !1195 !type !1196 {
entry:
    #dbg_value(ptr %ptr, !1268, !DIExpression(), !1283)
    #dbg_value(i64 %len, !1269, !DIExpression(), !1283)
    #dbg_value(i64 %disp_addr, !1270, !DIExpression(), !1283)
    #dbg_value(ptr %printf_func, !1271, !DIExpression(), !1283)
    #dbg_value(ptr %printf_arg, !1272, !DIExpression(), !1283)
    #dbg_value(ptr %ptr, !1273, !DIExpression(), !1283)
    #dbg_value(i64 -6148914691236517206, !1274, !DIExpression(), !1283)
    #dbg_value(i64 -6148914691236517206, !1275, !DIExpression(), !1283)
    #dbg_value(i64 0, !1274, !DIExpression(), !1283)
  %cmp83.not = icmp eq i64 %len, 0, !dbg !1284
  br i1 %cmp83.not, label %for.end43, label %for.body.lr.ph, !dbg !1285

for.body.lr.ph:                                   ; preds = %entry
    #dbg_value(ptr %ptr, !1273, !DIExpression(), !1283)
  %0 = tail call i1 @llvm.type.test(ptr %printf_func, metadata !"_ZTSFvPvPKczE"), !nosanitize !46
  %add = add i64 %disp_addr, %len
  %cmp1 = icmp ugt i64 %add, 4294967295
  %cond = select i1 %cmp1, ptr @.str, ptr @.str.1
  br i1 %0, label %for.body.preheader, label %trap, !dbg !1286, !nosanitize !46

for.body.preheader:                               ; preds = %for.body.lr.ph
  %1 = ptrtoint ptr %ptr to i64, !dbg !1287
    #dbg_value(i64 %1, !1273, !DIExpression(), !1283)
  br label %cont9.preheader, !dbg !1285

cont9.preheader:                                  ; preds = %cont39, %for.body.preheader
  %indvars.iv = phi i64 [ %len, %for.body.preheader ], [ %indvars.iv.next, %cont39 ]
  %address.085 = phi i64 [ %1, %for.body.preheader ], [ %add40, %cont39 ]
  %count.084 = phi i64 [ 0, %for.body.preheader ], [ %add42, %cont39 ]
  %umin87 = tail call i64 @llvm.umin.i64(i64 %indvars.iv, i64 16), !dbg !1288
  %umax88 = tail call i64 @llvm.umax.i64(i64 %umin87, i64 1), !dbg !1288
    #dbg_value(i64 %address.085, !1273, !DIExpression(), !1283)
    #dbg_value(i64 %count.084, !1274, !DIExpression(), !1283)
  %add2 = add i64 %count.084, %disp_addr, !dbg !1288
  tail call void (ptr, ptr, ...) %printf_func(ptr noundef %printf_arg, ptr noundef nonnull %cond, i64 noundef %add2) #7, !dbg !1286
    #dbg_value(i64 0, !1275, !DIExpression(), !1283)
  br label %cont9, !dbg !1289

trap:                                             ; preds = %for.body.lr.ph
  tail call void @llvm.ubsantrap(i8 2) #9, !dbg !1291, !nosanitize !46
  unreachable, !dbg !1286, !nosanitize !46

for.cond11.preheader:                             ; preds = %cont9
    #dbg_value(i64 %umax88, !1275, !DIExpression(), !1283)
  %cmp1279 = icmp ult i64 %indvars.iv, 16, !dbg !1292
  br i1 %cmp1279, label %cont14, label %cont29.lr.ph, !dbg !1295

cont9:                                            ; preds = %cont9.preheader, %cont9
  %i.077 = phi i64 [ %inc, %cont9 ], [ 0, %cont9.preheader ]
    #dbg_value(i64 %i.077, !1275, !DIExpression(), !1283)
  %add10 = add i64 %i.077, %address.085, !dbg !1296
  %2 = inttoptr i64 %add10 to ptr, !dbg !1299
  %3 = load i8, ptr %2, align 1, !dbg !1300, !tbaa !1225
  %conv = zext i8 %3 to i32, !dbg !1300
  tail call void (ptr, ptr, ...) %printf_func(ptr noundef %printf_arg, ptr noundef nonnull @.str.8, i32 noundef %conv) #7, !dbg !1301
  %inc = add nuw nsw i64 %i.077, 1, !dbg !1302
    #dbg_value(i64 %inc, !1275, !DIExpression(), !1283)
  %exitcond.not = icmp eq i64 %inc, %umax88, !dbg !1303
  br i1 %exitcond.not, label %for.cond11.preheader, label %cont9, !dbg !1289, !llvm.loop !1304

cont14:                                           ; preds = %for.cond11.preheader, %cont14
  %i.180 = phi i64 [ %inc16, %cont14 ], [ %umax88, %for.cond11.preheader ]
    #dbg_value(i64 %i.180, !1275, !DIExpression(), !1283)
  tail call void (ptr, ptr, ...) %printf_func(ptr noundef %printf_arg, ptr noundef nonnull @.str.9) #7, !dbg !1306
  %inc16 = add nuw nsw i64 %i.180, 1, !dbg !1308
    #dbg_value(i64 %inc16, !1275, !DIExpression(), !1283)
  %exitcond86.not = icmp eq i64 %inc16, 16, !dbg !1292
  br i1 %exitcond86.not, label %cont29.lr.ph, label %cont14, !dbg !1295, !llvm.loop !1309

cont29.lr.ph:                                     ; preds = %cont14, %for.cond11.preheader
  tail call void (ptr, ptr, ...) %printf_func(ptr noundef %printf_arg, ptr noundef nonnull @.str.4) #7, !dbg !1311
    #dbg_value(i64 0, !1275, !DIExpression(), !1283)
  %4 = inttoptr i64 %address.085 to ptr
  br label %cont29, !dbg !1312

cont29:                                           ; preds = %cont29.lr.ph, %cont29
  %i.282 = phi i64 [ 0, %cont29.lr.ph ], [ %inc37, %cont29 ]
    #dbg_value(i64 %i.282, !1275, !DIExpression(), !1283)
    #dbg_value(i8 poison, !1276, !DIExpression(), !1313)
  %arrayidx = getelementptr inbounds nuw i8, ptr %4, i64 %i.282, !dbg !1314
  %5 = load i8, ptr %arrayidx, align 1, !dbg !1314, !tbaa !1225
    #dbg_value(i8 %5, !1276, !DIExpression(), !1313)
  %conv30 = sext i8 %5 to i32, !dbg !1315
  %call = tail call i32 @isprint(i32 noundef %conv30) #7, !dbg !1316
  %tobool.not = icmp eq i32 %call, 0, !dbg !1316
  %conv35 = select i1 %tobool.not, i32 46, i32 %conv30, !dbg !1316
  tail call void (ptr, ptr, ...) %printf_func(ptr noundef %printf_arg, ptr noundef nonnull @.str.5, i32 noundef %conv35) #7, !dbg !1317
  %inc37 = add nuw nsw i64 %i.282, 1, !dbg !1318
    #dbg_value(i64 %inc37, !1275, !DIExpression(), !1283)
  %exitcond89.not = icmp eq i64 %inc37, %umax88, !dbg !1319
  br i1 %exitcond89.not, label %cont39, label %cont29, !dbg !1312, !llvm.loop !1320

cont39:                                           ; preds = %cont29
  tail call void (ptr, ptr, ...) %printf_func(ptr noundef %printf_arg, ptr noundef nonnull @.str.10) #7, !dbg !1322
  %add40 = add i64 %address.085, 16, !dbg !1323
    #dbg_value(i64 %add40, !1273, !DIExpression(), !1283)
  %add42 = add i64 %count.084, 16, !dbg !1324
    #dbg_value(i64 %add42, !1274, !DIExpression(), !1283)
  %cmp = icmp ult i64 %add42, %len, !dbg !1284
  %indvars.iv.next = add i64 %indvars.iv, -16, !dbg !1285
  br i1 %cmp, label %cont9.preheader, label %for.end43, !dbg !1285, !llvm.loop !1325

for.end43:                                        ; preds = %cont39, %entry
  ret void, !dbg !1327
}

ilovepi added a commit that referenced this issue Oct 30, 2024
Currently, the `DropTypeTests` parameter only fully works with phi nodes
and llvm.assume instructions. However, we'd like CFI to work in
conjunction with FatLTO, in so far as the bitcode section should be able
to contain the CFI instrumentation, while any incompatible bits are
dropped when compiling the object code.

To do that, we need to drop the llvm.type.test instructions everywhere,
and not just their uses in phi nodes. This patch updates the
LowerTypeTest pass so that uses are removed, and replaced with `true` in
all cases, and not just in phi nodes.

Addressing this will allow us to fix #112053 by modifying the FatLTO
pipeline.

Reviewers: pcc, nikic

Reviewed By: pcc

Pull Request: #112787
@EugeneZelenko EugeneZelenko added llvm:codegen ipo Interprocedural optimizations and removed llvm:SelectionDAG SelectionDAGISel as well labels Oct 31, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
compiler-rt:cfi Control Flow Integrity ipo Interprocedural optimizations llvm:codegen LTO Link time optimization (regular/full LTO or ThinLTO)
Projects
None yet
Development

Successfully merging a pull request may close this issue.

3 participants