This is an archive of the discontinued LLVM Phabricator instance.

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

Authored by nikic on Feb 21 2023, 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.Feb 21 2023, 3:03 AM
nikic requested review of this revision.Feb 21 2023, 3:03 AM
Herald added a project: Restricted Project. · View Herald TranscriptFeb 21 2023, 3:03 AM
fhahn accepted this revision.Mar 7 2023, 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.Mar 7 2023, 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.Mar 13 2023, 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.