Skip to content

Commit 252d019

Browse files
authored
[InstCombine] Drop UB-implying attrs/metadata after speculating an instruction (#85542)
When speculating an instruction in `InstCombinerImpl::FoldOpIntoSelect`, the call may result in undefined behavior. This patch drops all UB-implying attrs/metadata to fix this. Fixes #85536.
1 parent f849805 commit 252d019

File tree

2 files changed

+41
-0
lines changed

2 files changed

+41
-0
lines changed

llvm/lib/Transforms/InstCombine/InstructionCombining.cpp

+1
Original file line numberDiff line numberDiff line change
@@ -1650,6 +1650,7 @@ static Value *foldOperationIntoSelectOperand(Instruction &I, SelectInst *SI,
16501650
Value *NewOp, InstCombiner &IC) {
16511651
Instruction *Clone = I.clone();
16521652
Clone->replaceUsesOfWith(SI, NewOp);
1653+
Clone->dropUBImplyingAttrsAndMetadata();
16531654
IC.InsertNewInstBefore(Clone, SI->getIterator());
16541655
return Clone;
16551656
}

llvm/test/Transforms/InstCombine/intrinsic-select.ll

+40
Original file line numberDiff line numberDiff line change
@@ -240,3 +240,43 @@ define i32 @vec_to_scalar_select_vector(<2 x i1> %b) {
240240
%c = call i32 @llvm.vector.reduce.add.v2i32(<2 x i32> %s)
241241
ret i32 %c
242242
}
243+
244+
define i8 @test_drop_noundef(i1 %cond, i8 %val) {
245+
; CHECK-LABEL: @test_drop_noundef(
246+
; CHECK-NEXT: entry:
247+
; CHECK-NEXT: [[TMP0:%.*]] = call i8 @llvm.smin.i8(i8 [[VAL:%.*]], i8 0)
248+
; CHECK-NEXT: [[RET:%.*]] = select i1 [[COND:%.*]], i8 -1, i8 [[TMP0]]
249+
; CHECK-NEXT: ret i8 [[RET]]
250+
;
251+
entry:
252+
%sel = select i1 %cond, i8 -1, i8 %val
253+
%ret = call noundef i8 @llvm.smin.i8(i8 %sel, i8 0)
254+
ret i8 %ret
255+
}
256+
257+
define i1 @pr85536(i32 %a) {
258+
; CHECK-LABEL: @pr85536(
259+
; CHECK-NEXT: entry:
260+
; CHECK-NEXT: [[CMP1:%.*]] = icmp ult i32 [[A:%.*]], 31
261+
; CHECK-NEXT: [[SHL1:%.*]] = shl nsw i32 -1, [[A]]
262+
; CHECK-NEXT: [[ZEXT:%.*]] = zext i32 [[SHL1]] to i64
263+
; CHECK-NEXT: [[SHL2:%.*]] = shl i64 [[ZEXT]], 48
264+
; CHECK-NEXT: [[SHR:%.*]] = ashr exact i64 [[SHL2]], 48
265+
; CHECK-NEXT: [[TMP0:%.*]] = call i64 @llvm.smin.i64(i64 [[SHR]], i64 0)
266+
; CHECK-NEXT: [[TMP1:%.*]] = and i64 [[TMP0]], 65535
267+
; CHECK-NEXT: [[RET1:%.*]] = icmp eq i64 [[TMP1]], 0
268+
; CHECK-NEXT: [[RET:%.*]] = select i1 [[CMP1]], i1 [[RET1]], i1 false
269+
; CHECK-NEXT: ret i1 [[RET]]
270+
;
271+
entry:
272+
%cmp1 = icmp ugt i32 %a, 30
273+
%shl1 = shl nsw i32 -1, %a
274+
%zext = zext i32 %shl1 to i64
275+
%shl2 = shl i64 %zext, 48
276+
%shr = ashr exact i64 %shl2, 48
277+
%sel = select i1 %cmp1, i64 -1, i64 %shr
278+
%smin = call noundef i64 @llvm.smin.i64(i64 %sel, i64 0)
279+
%masked = and i64 %smin, 65535
280+
%ret = icmp eq i64 %masked, 0
281+
ret i1 %ret
282+
}

0 commit comments

Comments
 (0)