# NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py UTC_ARGS: --version 5 # RUN: llc %s -mtriple=x86_64-unknown -mattr=+ndd,+egpr -start-before=break-false-deps -show-mc-encoding -verify-machineinstrs -o - | FileCheck --check-prefixes=CHECK,RCDEFAULT %s # RUN: llc %s -mtriple=x86_64-unknown -mattr=+ndd,+egpr -start-before=break-false-deps -partial-reg-update-clearance=1 -verify-machineinstrs -show-mc-encoding -o - | FileCheck --check-prefixes=CHECK,RC1 %s # # Check that BreakFalseDeps detects cases where an ND instruction would cause a partial register write # if compressed to a legacy op. MIR has been modified to force different register assignments. # # For partial_write, the ADD16rr_ND is compressible, but will become a partial write after compression. # Compression is inhibited if the eax definition is within the partial-reg-update-clearance threshold. # # For no_partial_write, the ADD16rr_ND is incompressible hence it cannot become a partial write. # This case checks that an implicit-def of eax is not added by breakPartialRegDependency. # --- | define signext i16 @partial_write(ptr %p, i32 %a, i32 %b, i16 signext %x, i16 signext %y) #0 { ; RCDEFAULT-LABEL: partial_write: ; RCDEFAULT: # %bb.0: # %entry ; RCDEFAULT-NEXT: leal (%rdx,%rsi), %eax # encoding: [0x8d,0x04,0x32] ; RCDEFAULT-NEXT: movl %eax, (%rdi) # encoding: [0x89,0x07] ; RCDEFAULT-NEXT: addw %cx, %ax, %ax # encoding: [0x62,0xf4,0x7d,0x18,0x01,0xc8] ; RCDEFAULT-NEXT: retq # encoding: [0xc3] ; ; RC1-LABEL: partial_write: ; RC1: # %bb.0: # %entry ; RC1-NEXT: leal (%rdx,%rsi), %eax # encoding: [0x8d,0x04,0x32] ; RC1-NEXT: movl %eax, (%rdi) # encoding: [0x89,0x07] ; RC1-NEXT: addw %cx, %ax # EVEX TO LEGACY Compression encoding: [0x66,0x01,0xc8] ; RC1-NEXT: retq # encoding: [0xc3] entry: %add = add nsw i32 %b, %a store i32 %add, ptr %p, align 4 %add1 = trunc i32 %add to i16 %add2 = add i16 %add1, %x ret i16 %add2 } define signext i16 @no_partial_write(ptr %p, i32 %a, i32 %b, i16 signext %x, i16 signext %y) #0 { ; CHECK-LABEL: no_partial_write: ; CHECK: # %bb.0: # %entry ; CHECK-NEXT: addl %esi, %edx # EVEX TO LEGACY Compression encoding: [0x01,0xf2] ; CHECK-NEXT: movl %edx, (%rdi) # encoding: [0x89,0x17] ; CHECK-NEXT: addw %cx, %dx, %ax # encoding: [0x62,0xf4,0x7d,0x18,0x01,0xca] ; CHECK-NEXT: retq # encoding: [0xc3] entry: %add = add nsw i32 %b, %a store i32 %add, ptr %p, align 4 %add1 = trunc i32 %add to i16 %add2 = add i16 %add1, %x ret i16 %add2 } attributes #0 = { mustprogress nofree norecurse nosync nounwind willreturn memory(argmem: write) uwtable "min-legal-vector-width"="0" "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-cpu"="x86-64" "target-features"="+cmov,+cx16,+cx8,+egpr,+fxsr,+mmx,+ndd,+sse,+sse2,+x87" "tune-cpu"="generic" } ... --- name: partial_write tracksRegLiveness: true noVRegs: true noPhis: true isSSA: false body: | bb.0.entry: liveins: $ecx, $edx, $esi, $rdi renamable $eax = nsw ADD32rr_ND killed renamable $edx, killed renamable $esi, implicit-def dead $eflags MOV32mr killed renamable $rdi, 1, $noreg, 0, $noreg, renamable $eax :: (store (s32) into %ir.p) renamable $ax = ADD16rr_ND renamable $ax, renamable $cx, implicit-def dead $eflags, implicit killed $ecx, implicit $eax RET64 $ax ... --- name: no_partial_write tracksRegLiveness: true noVRegs: true noPhis: true isSSA: false body: | bb.0.entry: liveins: $ecx, $edx, $esi, $rdi renamable $edx = nsw ADD32rr_ND killed renamable $edx, killed renamable $esi, implicit-def dead $eflags MOV32mr killed renamable $rdi, 1, $noreg, 0, $noreg, renamable $edx :: (store (s32) into %ir.p) renamable $ax = ADD16rr_ND renamable $dx, renamable $cx, implicit-def dead $eflags, implicit killed $ecx, implicit killed $edx RET64 $ax ...