Files
clang-p2996/llvm/test/Transforms/NewGVN/cache-safe-phiofops.ll
ManuelJBrito 5b0dba13a5 [NewGVN] Fix caching for OpIsSafeForPhiOfOps (#98340)
The caching mechanism for 'OpIsSafeForPhiOfOps' is unsound. An operand
is deemed unsafe for PhiOfOps if it depends on a phi that resides in the
same block as the Phi block, i.e., where we are performing the PhiOfOps.
This is to avoid having to materialize the translated subexpressions. To
avoid redundant code walking, a cache is used to store these results.
Note, however, that since the safety is specific to the Phi block, we
cannot, in general, use the cached results for other blocks.

This patch addresses this by having a cache per block instead of a
single one for the entire function. closes #63335
2024-07-12 11:17:45 +01:00

101 lines
3.7 KiB
LLVM

; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --version 5
; RUN: opt -S -passes=newgvn < %s | FileCheck %s
define i32 @unsafe(i1 %arg, i32 %arg1) {
; CHECK-LABEL: define i32 @unsafe(
; CHECK-SAME: i1 [[ARG:%.*]], i32 [[ARG1:%.*]]) {
; CHECK-NEXT: [[BB:.*:]]
; CHECK-NEXT: br label %[[BB4:.*]]
; CHECK: [[BB4]]:
; CHECK-NEXT: br i1 [[ARG]], label %[[BB6:.*]], label %[[BB5:.*]]
; CHECK: [[BB5]]:
; CHECK-NEXT: br label %[[BB6]]
; CHECK: [[BB6]]:
; CHECK-NEXT: [[PHI:%.*]] = phi i32 [ [[ARG1]], %[[BB5]] ], [ 0, %[[BB4]] ]
; CHECK-NEXT: [[SREM:%.*]] = srem i32 [[ARG1]], [[PHI]]
; CHECK-NEXT: store i32 [[SREM]], ptr null, align 4
; CHECK-NEXT: br i1 [[ARG]], label %[[BB8:.*]], label %[[BB7:.*]]
; CHECK: [[BB7]]:
; CHECK-NEXT: br i1 true, label %[[BB8]], label %[[BB5]]
; CHECK: [[BB8]]:
; CHECK-NEXT: [[PHIOFOPS:%.*]] = phi i32 [ [[ARG1]], %[[BB6]] ], [ 0, %[[BB7]] ]
; CHECK-NEXT: [[PHI9:%.*]] = phi i32 [ 0, %[[BB7]] ], [ 1, %[[BB6]] ]
; CHECK-NEXT: store i32 [[PHIOFOPS]], ptr null, align 4
; CHECK-NEXT: br label %[[BB4]]
;
bb:
br label %bb4
bb4: ; preds = %bb8, %bb
br i1 %arg, label %bb6, label %bb5
bb5: ; preds = %bb7, %bb4
br label %bb6
bb6: ; preds = %bb5, %bb4
%phi = phi i32 [ %arg1, %bb5 ], [ 0, %bb4 ]
%or = or i32 %phi, %arg1
%srem = srem i32 %or, %phi
store i32 %srem, ptr null, align 4
br i1 %arg, label %bb8, label %bb7
bb7: ; preds = %bb6
br i1 true, label %bb8, label %bb5
bb8: ; preds = %bb7, %bb6
%phi9 = phi i32 [ 0, %bb7 ], [ 1, %bb6 ]
%mul = mul i32 %phi9, %or
store i32 %mul, ptr null, align 4
br label %bb4
}
define i32 @unsafe_load(i1 %arg) {
; CHECK-LABEL: define i32 @unsafe_load(
; CHECK-SAME: i1 [[ARG:%.*]]) {
; CHECK-NEXT: [[BB:.*:]]
; CHECK-NEXT: br label %[[BB1:.*]]
; CHECK: [[BB1]]:
; CHECK-NEXT: br i1 [[ARG]], label %[[BB3:.*]], label %[[BB2:.*]]
; CHECK: [[BB2]]:
; CHECK-NEXT: br label %[[BB3]]
; CHECK: [[BB3]]:
; CHECK-NEXT: [[PHI4:%.*]] = phi i32 [ 1, %[[BB2]] ], [ 0, %[[BB1]] ]
; CHECK-NEXT: [[LOAD:%.*]] = load i32, ptr null, align 4
; CHECK-NEXT: [[SREM:%.*]] = srem i32 [[LOAD]], [[PHI4]]
; CHECK-NEXT: store i32 [[SREM]], ptr null, align 4
; CHECK-NEXT: br i1 [[ARG]], label %[[BB6:.*]], label %[[BB5:.*]]
; CHECK: [[BB5]]:
; CHECK-NEXT: br i1 true, label %[[BB6]], label %[[BB2]]
; CHECK: [[BB6]]:
; CHECK-NEXT: [[PHIOFOPS:%.*]] = phi i32 [ [[LOAD]], %[[BB3]] ], [ 0, %[[BB5]] ]
; CHECK-NEXT: [[PHI7:%.*]] = phi i32 [ 0, %[[BB5]] ], [ 1, %[[BB3]] ]
; CHECK-NEXT: store i32 [[PHIOFOPS]], ptr null, align 4
; CHECK-NEXT: br label %[[BB1]]
;
bb:
br label %bb1
bb1: ; preds = %bb6, %bb
br i1 %arg, label %bb3, label %bb2
bb2: ; preds = %bb5, %bb1
%phi = phi i32 [ 1, %bb1 ], [ 0, %bb5 ]
br label %bb3
bb3: ; preds = %bb2, %bb1
%phi4 = phi i32 [ %phi, %bb2 ], [ 0, %bb1 ]
%load = load i32, ptr null, align 4
%srem = srem i32 %load, %phi4
store i32 %srem, ptr null, align 4
br i1 %arg, label %bb6, label %bb5
bb5: ; preds = %bb3
br i1 true, label %bb6, label %bb2
bb6: ; preds = %bb5, %bb3
%phi7 = phi i32 [ 0, %bb5 ], [ 1, %bb3 ]
%mul = mul i32 %phi7, %load
store i32 %mul, ptr null, align 4
br label %bb1
}