Page MenuHomePhabricator

[IPSCCP] Don't require noundef for !range annotation
ClosedPublic

Authored by nikic on Tue, Feb 21, 3:03 AM.

Details

Summary

Since https://reviews.llvm.org/D141386 !range violations return poison instead of causing immediate undefined behavior. As such, it is fine for IPSCCP to infer !range even if the value might be poison. (The value cannot be undef as this would promote undef to poison, but this is already checked separately.)

This basically undoes the late change done to D83952, restoring it to its original version (which is now valid).

Diff Detail

Event Timeline

nikic created this revision.Tue, Feb 21, 3:03 AM
nikic requested review of this revision.Tue, Feb 21, 3:03 AM
Herald added a project: Restricted Project. · View Herald TranscriptTue, Feb 21, 3:03 AM
fhahn accepted this revision.Tue, Mar 7, 6:56 AM

LGTM, thanks! The range is guaranteed to not include undef as per an earlier check.

This revision is now accepted and ready to land.Tue, Mar 7, 6:56 AM
This revision was automatically updated to reflect the committed changes.

I saw following case failed due to this commit with IPSCCPPass opt -passes="ipsccp"

; ModuleID = 'ld-temp.o'
source_filename = "ld-temp.o"
target datalayout = "e-m:e-i64:64-n32:64-S128-v256:256:256-v512:512:512"
target triple = "powerpc64le-unknown-linux-gnu"

; Function Attrs: noinline nounwind optnone uwtable
define internal <2 x i64> @cntlzVector(<2 x i64> noundef %0) #0 {
  %2 = alloca <2 x i64>, align 16
  %3 = alloca <2 x i64>, align 16
  store <2 x i64> %0, ptr %3, align 16
  %4 = load <2 x i64>, ptr %3, align 16
  store <2 x i64> %4, ptr %2, align 16
  %5 = load <2 x i64>, ptr %2, align 16
  %6 = call <2 x i64> @llvm.ctlz.v2i64(<2 x i64> %5, i1 false)
  ret <2 x i64> %6
}

; Function Attrs: mustprogress nocallback nofree nosync nounwind speculatable willreturn memory(none)
declare <2 x i64> @llvm.ctlz.v2i64(<2 x i64>, i1 immarg) #1

; Function Attrs: noinline nounwind optnone uwtable
define dso_local signext i32 @main() #0 {
  %1 = alloca i32, align 4
  %2 = alloca <2 x i64>, align 16
  store i32 0, ptr %1, align 4
  %3 = load <2 x i64>, ptr %2, align 16
  %4 = call <2 x i64> @cntlzVector(<2 x i64> noundef %3)
  store <2 x i64> %4, ptr %2, align 16
  ret i32 0
}

attributes #0 = { noinline nounwind optnone uwtable "frame-pointer"="all" "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-cpu"="ppc64le" "target-features"="+altivec,+bpermd,+crbits,+crypto,+direct-move,+extdiv,+htm,+isa-v206-instructions,+isa-v207-instructions,+power8-vector,+vsx,-isa-v30-instructions,-power9-vector,-privileged,-quadword-atomics,-rop-protect,-spe" }
attributes #1 = { mustprogress nocallback nofree nosync nounwind speculatable willreturn }

!llvm.ident = !{!0}
!llvm.module.flags = !{!1, !2, !3, !4, !5, !6, !7, !8}

!0 = !{!""}
!1 = !{i32 1, !"wchar_size", i32 4}
!2 = !{i32 8, !"PIC Level", i32 2}
!3 = !{i32 7, !"PIE Level", i32 2}
!4 = !{i32 7, !"uwtable", i32 2}
!5 = !{i32 7, !"frame-pointer", i32 2}
!6 = !{i32 1, !"ThinLTO", i32 0}
!7 = !{i32 1, !"EnableSplitLTOUnit", i32 1}
!8 = !{i32 1, !"LTOPostLink", i32 1}
nikic added a comment.Mon, Mar 13, 3:09 AM

@tingwang Thanks for the report. Here's a reduced test case:

define internal <2 x i64> @ctlz(<2 x i64> %arg) {
  %res = call <2 x i64> @llvm.ctlz.v2i64(<2 x i64> %arg, i1 false)
  ret <2 x i64> %res
}

define <2 x i64> @caller(<2 x i64> %arg) {
  %res = call <2 x i64> @ctlz(<2 x i64> %arg)
  ret <2 x i64> %res
}

declare <2 x i64> @llvm.ctlz.v2i64(<2 x i64>, i1)

The problem is that !range is currently not supported for vector types.

After this change one of our bots started failing a gcc test suite test on our SVE bot. However on closer inspection, it was that clang is now able to tail call some things it previously couldn't. Which is actually a good thing!

I've posted a fix for the test file https://reviews.llvm.org/D146143.