https://bugs.llvm.org/show_bug.cgi?id=47927

            Bug ID: 47927
           Summary: Shift UB in emitLegacyZExt when "from" type is >=
                    64-bit
           Product: libraries
           Version: trunk
          Hardware: PC
                OS: All
            Status: NEW
          Severity: normal
          Priority: P
         Component: DebugInfo
          Assignee: unassignedb...@nondot.org
          Reporter: v...@apple.com
                CC: jdevliegh...@apple.com, keith.wal...@arm.com,
                    llvm-bugs@lists.llvm.org,
                    paul_robin...@playstation.sony.com

Clang trips an "out of bounds shift" UBSan diagnostic when compiling
__fixunsxfti from compiler-rt.

A reduced test:

```
; RUN: llc -filetype=obj -o - %s | llvm-dwarfdump -

define void @t(i64 %x) !dbg !6 {
  call void @llvm.dbg.value(metadata i64 %x, metadata !9,
                            metadata !DIExpression(DW_OP_LLVM_convert, 64,
DW_ATE_unsigned,
                                                   DW_OP_LLVM_convert, 128,
DW_ATE_unsigned)), !dbg !11
  ret void, !dbg !12
}

declare void @llvm.dbg.value(metadata, metadata, metadata)

!llvm.dbg.cu = !{!0}
!llvm.debugify = !{!3, !4}
!llvm.module.flags = !{!5}

!0 = distinct !DICompileUnit(language: DW_LANG_C, file: !1, producer:
"debugify", isOptimized: true, runtimeVersion: 0, emissionKind: FullDebug,
enums: !2)
!1 = !DIFile(filename: "legacy-zext.ll", directory: "/")
!2 = !{}
!3 = !{i64 2}
!4 = !{i64 1}
!5 = !{i64 2, !"Debug Info Version", i32 3}
!6 = distinct !DISubprogram(name: "t", linkageName: "t", scope: null, file: !1,
line: 1, type: !7, scopeLine: 1, spFlags: DISPFlagDefinition |
DISPFlagOptimized, unit: !0, retainedNodes: !8)
!7 = !DISubroutineType(types: !2)
!8 = !{!9}
!9 = !DILocalVariable(name: "1", scope: !6, file: !1, line: 1, type: !10)
!10 = !DIBasicType(name: "ty64", size: 32, encoding: DW_ATE_unsigned)
!11 = !DILocation(line: 1, column: 1, scope: !6)
!12 = !DILocation(line: 2, column: 1, scope: !6)
```

Here's the code that trips the UBSan diagnostic:

```
void DwarfExpression::emitLegacyZExt(unsigned FromBits) {
  // (X & (1 << FromBits - 1))
  emitOp(dwarf::DW_OP_constu);
  emitUnsigned((1ULL << FromBits) - 1); //<<< HERE (FromBits >= 64)
  emitOp(dwarf::DW_OP_and);
}
```

This legacy zext operation is a fallback DW_OP_convert implementation when
targeting Dwarf 4.

One way to address the diagnostic might be to plumb APInt through
DwarfExpression, MCStreamer, MCAsmStreamer, ByteStreamer, DIEInteger and so on.
I'm not sure whether that's a direction others in the community want to go. The
complexity of the change seems somewhat out of proportion to the problem it's
trying to fix.

Is there some other way to implement the legacy zext? Or should we try not to
emit it if we can't emit the mask?

-- 
You are receiving this mail because:
You are on the CC list for the bug.
_______________________________________________
llvm-bugs mailing list
llvm-bugs@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-bugs

Reply via email to