[llvm] [GVN][NewGVN][Local] Handle attributes for function calls after CSE (PR #114011)

Nikita Popov via llvm-commits llvm-commits at lists.llvm.org
Fri Nov 1 02:28:52 PDT 2024


https://github.com/nikic commented:

The general implementation approach here looks incorrect to me. You can't really restrict replacements after the fact in GVN, you need to do so during value numbering.

Consider this minor variation of the test case:
```
define i1 @bucket2(i32 noundef %x) {
; CHECK-LABEL: define i1 @bucket2(
; CHECK-SAME: i32 noundef [[X:%.*]]) {
; CHECK-NEXT:    [[CMP1:%.*]] = icmp sgt i32 [[X]], 0
; CHECK-NEXT:    [[CTPOP1:%.*]] = tail call range(i32 1, 32) i32 @llvm.ctpop.i32(i32 zeroext [[X]])
; CHECK-NEXT:    [[CTPOP1INC:%.*]] = add i32 [[CTPOP1]], 1
; CHECK-NEXT:    [[CMP2:%.*]] = icmp samesign ult i32 [[CTPOP1INC]], 3
; CHECK-NEXT:    [[COND:%.*]] = select i1 [[CMP1]], i1 [[CMP2]], i1 false
; CHECK-NEXT:    br i1 [[COND]], label %[[IF_THEN:.*]], label %[[IF_ELSE:.*]]
; CHECK:       [[IF_ELSE]]:
; CHECK-NEXT:    [[CTPOP2:%.*]] = tail call range(i32 0, 33) i32 @llvm.ctpop.i32(i32 [[X]])
; CHECK-NEXT:    [[RES:%.*]] = icmp eq i32 [[CTPOP1INC]], 2
; CHECK-NEXT:    ret i1 [[RES]]
; CHECK:       [[IF_THEN]]:
; CHECK-NEXT:    ret i1 false
;
  %cmp1 = icmp sgt i32 %x, 0
  %ctpop1 = tail call range(i32 1, 32) i32 @llvm.ctpop.i32(i32 zeroext %x)
  %ctpop1inc = add i32 %ctpop1, 1
  %cmp2 = icmp samesign ult i32 %ctpop1inc, 3
  %cond = select i1 %cmp1, i1 %cmp2, i1 false
  br i1 %cond, label %if.then, label %if.else

if.else:
  %ctpop2 = tail call range(i32 0, 33) i32 @llvm.ctpop.i32(i32 %x)
  %ctpop2inc = add i32 %ctpop2, 1
  %res = icmp eq i32 %ctpop2inc, 2
  ret i1 %res

if.then:
  ret i1 false
}
```

This just adds a `zeroext` dummy attribute to make sure the two ctpop calls are not combined directly, and an extra `add 1` after them. Note that the adds *will* get CSEd, because the canBeReplacedBy check is specifically on the calls, not on any later instructions that are numbered based on the incorrect assumption that the calls are equivalent.

https://github.com/llvm/llvm-project/pull/114011


More information about the llvm-commits mailing list